עברית

Create and use a Developer API key

Create a personal server-side key, choose read/write/publish access, call the API safely, paginate results, respect quotas and recover from uncertain writes.

Last updated: · Read as Markdown

What this is for

Use the Developer API to connect your own backend to LeadKnight: read campaigns, posts, accounts, destinations, media, analytics and posting activity; maintain CRM contacts; upload media; and create, publish or control reviewed campaign work when authorized. It is a server-to-server API, separate from the future Claude/ChatGPT connector.

The production resource base URL is https://api.lead-knight.com/v1. Keep the /v1 prefix on resource requests. The API reference describes exact operations and fields. The public OpenAPI document is outside /v1, requires no key and contains no account data; it is unavailable when the Developer API is disabled.

Before you start

  • Sign in as the person the integration should act as, select the correct workspace and confirm the current role and seat allow the intended operations.
  • Prepare a backend and private secret manager or server environment. Do not put the key in browser JavaScript, a mobile app, a URL, source control, analytics or logs.
  • Choose the minimum key permissions. A key belongs to one person and one workspace; it is not a workspace-wide administrator credential.
  • For publication, first connect and authorize the actual accounts, destinations and recipients. API access does not grant missing account access, recipient consent, sender permissions or platform eligibility.

If you do not see Developer API in Settings, it may not be enabled for your workspace yet. When globally disabled, a card with no existing keys is hidden; existing personal keys remain listed and revocable, but creation and API use are disabled.

Create the key in Settings

  1. Open Settings → Developer API. Check API base URL and open API documentation (OpenAPI) if you need the machine-readable contract.
  2. Select Create API key. The dialog shows Workspace. Verify it before continuing; changing a request header later cannot move this key to another workspace.
  3. Enter Key name, identifying the backend or app. Use 1–100 characters without control characters or invalid Unicode. Invalid names show a message you can correct before creation.
  4. Under Permissions, choose one of the levels below. The default is Read only.
  5. Under Key lifetime, choose 30 days, 90 days, 180 days, 1 year or No expiry. The default is 90 days. No expiry does not survive revocation, lost membership or loss of current permissions.
  6. Select Create API key. On success, Save your API key now replaces the form and identifies the workspace. The One-time API key is the only chance to see the secret.
  7. Select Copy key and save it privately on your server. If copying fails, the selected field can be copied manually; you can also select Copy key again. Do not close the dialog before saving.
  8. Select I've saved the key. Under Your API keys, confirm the name, workspace, permission level, masked prefix/last four characters, expiry and last-use information. Load more loads further keys.

Closing the secret dialog, leaving the screen, or changing identity/workspace discards the displayed secret. It cannot be recovered. If creation reports an uncertain result or the secret was lost, use Refresh list, revoke any new key you did not save, and create a replacement. Do not repeatedly submit key creation to find out whether the first request worked.

Choose the correct permission ceiling

Settings option API value What it permits, subject to current access
Read only read Supported resource reads. No uploads, CRM changes or publishing.
Read and write write Includes read, CRM creation/updates/notes, uploads, standalone draft campaigns and unarmed post drafts.
Read, write and publish publish Includes read and write, plus explicit publication, pause/resume/archive and edits to already-granted or started work.

Editing a previously granted or started post requires publish authority even if the new request says intent: "draft": withdrawing a grant can cancel work. The same principle applies to campaign edits after approval or execution history exists. A key's ceiling never bypasses the person's current role, seat, visibility or channel rules. Limited preparation-state allowances do not grant publishing rights.

Make a first server-side read

  1. Load the stored key privately into your backend. The token starts with lk_api_; do not replace it with a first-party session token or an MCP token.
  2. Make an HTTPS GET to https://api.lead-knight.com/v1/campaigns with Authorization: Bearer <key>. Replace the placeholder privately; never put the key in the URL.
  3. Inspect the HTTP status, JSON response and rate-limit headers. A successful collection response includes items and nextCursor.
  4. Keep the key's workspace binding. Prefer omitting X-Workspace-Id. A conflicting value returns 400 workspace_mismatch; that header cannot select a different workspace.
  5. Continue with another read operation from the reference before implementing changes or publishing.

Requests carrying Origin, Sec-Fetch-Site, Sec-Fetch-Dest or Sec-Fetch-User are refused with 401 browser_request_not_allowed. This protects against accidental browser use; do not solve it by embedding a key in a different browser transport. Move the integration to your server. A lone Sec-Fetch-Mode header from server-side fetch is not refused for that reason.

Keys do not authenticate ordinary app APIs or the signed-in key-management endpoints. Use Settings to create and revoke your own keys; being a workspace administrator does not expose another person's keys.

Supported work and important boundaries

Area Supported operations and requirements
Campaigns and posts List/read; create a standalone draft campaign; create or fully update a reviewed post; limited campaign edits; pause/resume selected or all cards; archive. Use the exact request shapes in the reference.
Accounts and destinations Discover permitted Facebook identities, official connected accounts and destinations. A Facebook identity ID is not an official connected-account ID. Group destinations include the identities that can reach them.
Media List visible, attachable media and upload exactly one multipart file, with no additional fields. JPEG, PNG, WebP and GIF: up to 10 MiB; MP4: up to 256 MiB. Actual content and type are validated.
Analytics and activity Analytics requires ISO datetime from and to, with to later than from. Posting activity supports its own date/period/network filters and continuation fields.
CRM List/read/create/update visible contacts, change/request ownership, create/delete notes, and read stages and members. At least a phone or email is needed on creation. Visibility and private-field rules remain in force.
Outbound events New contact, contact updated and campaign status changed notifications through Webhooks, configured in Settings.

There are no Developer API operations here for direct paid-AI generation/editing, billing, paid-ad spending, calendar or real-estate-specific CRM fields. Five campaign channels are supported: social feeds, Facebook groups, WhatsApp, email and Marketplace, each with its existing approvals, accounts, sender, media, consent and eligibility rules. Discovery does not include Gmail senders or WhatsApp accounts; do not invent account or recipient IDs.

Paginate without losing your place

  1. Begin a list without a cursor. limit defaults to 20, normally accepts 1–50, and allows up to 500 for destinations.
  2. Read items and retain nextCursor. A null cursor means there is no further page in this continuation.
  3. Pass a non-null returned cursor unchanged to the same collection with the same relevant filters and identity/workspace. Do not decode, construct or round its timestamps. Cursor length is limited to 2,048 characters.
  4. For campaign-post lists, retain the same parent campaign. For destinations, retain the bound destination filters. If the server returns 400 invalid_cursor, restart the correct list instead of repairing the cursor.
  5. Treat pagination as a changing live collection, not a snapshot. Records can change between requests.

Posting activity has a different envelope: activity, nextCursor and bulkSendsNextCursor. Retain its filters and limit with the cursor; the separate bulk-send continuation uses network=whatsapp. CRM stage/member directory responses have items but are not ordinary cursor-paged collections. Consult the reference for each response rather than assuming every endpoint shares one shape.

Respect rate limits

Default budgets are 60 requests per minute per key and 1,000 requests per UTC day per workspace and issuing person, shared across that person's keys. Operators can configure different limits, so use response headers as the authority. The minute window lasts 60 seconds from its first admitted request; the daily window resets at 00:00 UTC.

Header Meaning
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset Per-key minute limit, remaining requests and reset time.
X-RateLimit-Day-Limit, X-RateLimit-Day-Remaining, X-RateLimit-Day-Reset Shared daily limit, remaining requests and reset time.
Retry-After On quota exhaustion, how many seconds to wait.

Reset times are Unix epoch seconds. Authenticated reads, retries, permission/seat refusals and conflicting workspace headers consume budget. Rotation does not reset the shared day budget. Earlier transport/IP refusals may not include developer-quota headers. A 429 means wait for the indicated interval; unavailable quota infrastructure returns 503 rather than allowing unrestricted traffic.

Make changes without accidental duplicates

Durable request identity

Before sending campaign creation, campaign edits, post writes, pause/resume/archive or note creation, store the method, target, exact reviewed request body and a stable Idempotency-Key. Operation keys are 1–255 visible ASCII characters with no spaces. Reuse the same key only for the same logical operation and unchanged body. Receipts survive API key rotation for the same person/workspace; new credentials do not make an old operation new.

Contact creation uses required externalId instead, 1–200 visible ASCII characters without spaces. It is workspace-wide find-or-create, not an upsert: 201 creates and 200 returns the current readable existing contact without overwriting it. external_id_in_use does not disclose an unreadable contact. duplicate_contact is a separate existing phone/email match and can include the existing contactId.

Uploads do not have an idempotency guarantee. Repeating an upload can create another asset. Unused staged assets become cleanup-eligible after 24 hours; do not treat an upload link or temporary URL as permanent storage.

Reviewed content and publication

  1. Create the draft campaign and retain its returned ID.
  2. Upload needed media and retain real asset IDs. Select currently authorized accounts, destinations and consenting recipients.
  3. Assemble and review the full post, complete desired channel-card set, schedules and channel-specific consent/caps. Use intent: "draft" to save without granting sends or intent: "publish" to explicitly approve that exact content and configuration. A schedule of now may stage work immediately.
  4. For updates, retain the reviewed expectedRevision. A PUT /v1/posts/{id} replaces desired post/card state; it is not a partial patch. Include stored card IDs to retain them and omit an old card only when intentionally removing it.
  5. Retain your original reviewed configuration. Public GET omits private card configuration, recipient and sender selections; it is not an editable template. Never copy GET straight into PUT or silently combine a new revision with old content.
  6. Inspect returned per-card outcomes and later activity. Accepted work can set an unavailable channel aside; a current grant or active/finished card is not proof of external delivery.

An uncertain response is not proof of failure. Inspect current state first. Deliberate replay of a keyed operation keeps the original method, target, body, operation key and reviewed revision. Do not add automatic write/upload retries. A new edit needs a new review and operation key, not a modified consumed request.

Pause and archive stop eligible future/stoppable work; they cannot recall provider requests already in flight, delete already-published content or stop independent paid-ad budgets.

Read errors and recover

Errors are flat JSON with error and message, not a nested provider error. Validation may include details.issues with up to eight safe path/message entries; requestId is optional. Keep the HTTP status along with the error token.

Status or symptom Meaning and next step
400 Invalid input, header or cursor. Remove unknown fields and correct the documented shape; restart a mismatched list.
401 Invalid/expired/revoked key, lost membership or forbidden browser transport. Check the server-side credential and current membership; do not expose the key while debugging.
403 Current key ceiling, role, visibility or seat does not permit the operation. Fix actual access rather than repeatedly retrying.
404 Resource absent/inaccessible or API disabled. Confirm the base path, real IDs and availability.
409 operation_key_conflict A consumed key is being used with changed content/action. Recover the original request; use a new key only for a genuinely new operation.
409 post_changed Reviewed revision is stale. Inspect current status, reconcile retained configuration, review again and submit a new operation. Do not blindly increment the revision.
409 posting_busy with retryable: true The edit rolled back because cancellation was contended. After contention clears, deliberately retry the same full request/key.
409 archive_cleanup_incomplete with retryable: true The campaign is archived but cancellation is incomplete. Repeat the same archive request/key to finish cleanup; do not reactivate it.
410 A consumed resource was deleted. Replaying its key cannot create a replacement.
413 / 415 Upload too large / unsupported type. Prepare a supported real file within its bound.
422 Domain refusal, such as a send exceeding its approved cap. Review and correct the business request.
429 Wait according to Retry-After and quota reset headers.
500 / uncertain write Outcome may be unknown. Inspect state before any deliberate same-key replay. Never assume the write failed.
503 A required dependency is unavailable. Preserve your operation journal and avoid an uncontrolled retry loop.

The retryable flag is not present on every error; absence is not permission to repeat a mutation unchanged.

Rotate or revoke a key

  1. Create a replacement with the minimum permissions and suitable expiry.
  2. Store it privately, update the backend and confirm the replacement can make the intended read.
  3. Under Your API keys, select the old key's Revoke. Review Revoke {name}? and the warning that apps lose access immediately.
  4. Confirm Revoke. The key becomes Revoked and cannot be restored. Expired keys also cannot authenticate.
  5. If revocation's outcome is uncertain, use Refresh list to check the state before repeating it. If a key leaked, revoke it rather than relying on expiry.

For signed event delivery, add a webhook in Settings rather than sending a bearer key to the receiver. Verify webhook-id, webhook-timestamp and webhook-signature over the raw body using the separate whsec_ secret. Check a five-minute timestamp tolerance, compare HMAC signatures in constant time and deduplicate IDs durably for 30 days. The webhook guide gives the exact signing construction and delivery behavior.