Skip to content
Signal
Dashboard
Get started

API conventions

Origins, identifiers, timestamps, pagination, errors, rate limits and safe retries.

Base URL

Set LINKT_API_URL to the API origin, without a path. Every sample adds /v2. Production uses https://api.signal.linkt.ai; staging uses https://api.sandbox.signal.linkt.ai.

Send an organization API key as Authentication describes. Requests read and change only that organization. A resource outside the organization gives 404 when the request passes its permission checks.

Identifiers and timestamps

Resource IDs are lowercase, hyphenated UUIDs. Treat IDs and cursors as opaque. get_me returns organization.id as a 24-character hexadecimal identifier; it is not a resource UUID.

Times are RFC 3339 UTC strings with milliseconds and a Z suffix, such as 2026-09-23T12:00:00.000Z.

Request bodies and filters

Unknown fields in typed request models give 422. This includes nested signal_types items on monitor create and update. Import rows use typed inputs; each operation defines its accepted identity fields. See Import.

Unknown query parameters are ignored. Check each filter name against the API reference; a misspelt filter can return an unfiltered list.

Pagination

list_campaigns, search_accounts, search_people, list_monitors, list_signals and list_runs return data and next_cursor. limit is 1 to 100, with a default of 25. Continue while next_cursor is non-null, using the same filters and limit. A page can contain fewer items than the limit before the last page.

Accounts, people, campaigns and monitors use ascending ID order. Runs and signals use descending order. Read Paginate a list for the procedure.

Error envelope

Errors return error.code, error.message and nullable error.details. Use the code for program decisions; message text can change. See the Errors reference.

Rate limit

The rate limit counts the requests of each API key. The default limit is 100 requests in a fixed 60-second window. Each response has these headers:

  • X-RateLimit-Limit: the number of requests in one window.
  • X-RateLimit-Remaining: the number of requests left in the current window.
  • X-RateLimit-Reset: the Unix time when the window resets.

A request over the limit gives 429 with a Retry-After header. The 429 body uses the V2 envelope:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Please retry after the specified time.",
    "details": { "retry_after": 12 }
  }
}

Retry-After is at least 1 second. Wait that long before another request.

Retry safely

  • Retry a 429 response after the Retry-After time. Honor the header on authentication 503 responses too.
  • For 409, inspect error.code and details.retryable. Follow the cause-specific conflict guidance.
  • Retry reads after a 500 or 503 response up to 3 times, with increasing delays. Retry creates and paid starts with the same Idempotency-Key; without a key, first check whether the initial request succeeded.
  • Do not retry a 401, 403, 404 or 422 response without a change to the request.
  • Send an Idempotency-Key header with each create and start: create_campaign, create_monitor, run_monitor, start_discovery, start_import and upload_import. Without the header, a retry of these operations can start a second paid run or create a second resource.

Idempotency-Key

The value is 1 to 255 printable ASCII characters, for example a UUID. Make a new value for each new request, and send the same value when you retry that request.

CaseResult
The first request succeededSignal returns the stored status and body again, with the header Idempotency-Replayed: true. No work starts.
The first request is still in progress409 idempotency_in_progress, with details.retryable: true. Wait, then retry with the same key and body.
The first request failedSignal runs the request again.
The same key with another body422 with the code idempotency_key_reused.
Signal cannot reach its key store503 with the code service_unavailable. No work starts.

Signal keeps a key for 24 hours after a successful request. A request without the header does not use the key store.

On this page