API Reference
REST endpoints for contacts, templates, messages, media, campaigns and webhooks.
The Lynkist Public API is a JSON-over-HTTPS API. Every resource your dashboard manipulates — contacts, templates, messages, media, campaigns and the outgoing webhook subsystem itself — is reachable through this surface.
Per-resource Markdown references live in the sidebar under API Reference — each page lists the endpoints, request/response shapes, and curl examples for one resource.
A hosted, public-API-only interactive explorer (filtered OpenAPI sub-app + Swagger UI) is on
the roadmap. We intentionally do not expose the raw FastAPI /docs in production — the
process hosts internal, dashboard and public routers behind a single OpenAPI document, and we
don't want internal routes enumerable from the public internet. Track Changelog
for the public explorer's ship date.
Base URL
| Environment | Base URL |
|---|---|
| Production | https://api.lynkist.io/api/v1/public |
| Sandbox | Same URL, but call with a lk_sk_test_… key |
Every endpoint in these docs is relative to the base URL above. For example, GET /contacts
means GET https://api.lynkist.io/api/v1/public/contacts.
The dashboard-only API-key management endpoints live on a separate, JWT-authenticated mount at
/{tenant}/api/v1/settings/api-keys — they are not part of the Public API and cannot be
reached with a bearer token. See Authentication.
Authentication
Every request must include an Authorization: Bearer <api_key> header. Keys look like
lk_sk_live_<40-hex> or lk_sk_test_<40-hex>. See Authentication
for scopes, rotation, and IP allowlists.
curl https://api.lynkist.io/api/v1/public/contacts \
-H "Authorization: Bearer $LYNKIST_API_KEY"Resources
| Resource | Path prefix | Reference |
|---|---|---|
| Contacts | /contacts | Contacts API |
| Templates | /templates | Templates API |
| Messages | /messages | Messages API |
| Media | /media | Media API |
| Campaigns | /campaigns | Campaigns API |
| Webhooks | /webhooks | Webhook management API |
Versioning
The API is versioned via URL prefix (/api/v1/public/…). Breaking changes ship as a new major
version; additive changes (new fields, new endpoints, new optional parameters) land in the
current version without notice. We aim to support each major version for at least 12 months
after its successor is announced.
Pagination
List endpoints use offset pagination. Pass ?page= and ?limit= as query parameters
(limit is capped at 100 unless an endpoint says otherwise).
curl "https://api.lynkist.io/api/v1/public/contacts?page=2&limit=50" \
-H "Authorization: Bearer $LYNKIST_API_KEY"Every paginated response wraps the items under data and exposes a pagination envelope:
{
"data": [ /* items */ ],
"pagination": {
"page": 2,
"limit": 50,
"total_items": 134,
"total_pages": 3,
"has_next": true,
"has_prev": true
}
}Stop paging when has_next is false.
Idempotency
All POST, PUT, PATCH and DELETE requests accept an Idempotency-Key header. The first
response is cached and any retry with the same key — even a different request body — replays the
cached response.
curl -X POST https://api.lynkist.io/api/v1/public/messages/template \
-H "Authorization: Bearer $LYNKIST_API_KEY" \
-H "Idempotency-Key: 7c4d2e1a-…" \
-H "Content-Type: application/json" \
-d '{ "to": "+91…", "template_name": "order_confirmation", "language": "en_US" }'The cache is scoped to the bearer token (not to your tenant) and entries live for 24 hours. Use a UUID v4 per logical operation.
Request IDs
Every response — success or error — includes an X-Request-Id header. If your client sends one
on the request, we honour it; otherwise we mint a req_<12-hex> value. Log it on your side; it
is the single fastest signal we can correlate against on ours.
Rate limits
Every response carries X-RateLimit-* headers. When you exceed your plan's per-minute or
per-day budget the API returns 429 Too Many Requests with a Retry-After header. See
Rate Limits for the per-plan numbers and recommended client behaviour.
Errors
Errors are returned with a standard HTTP status and a small JSON body. See Errors for the envelope shape, status code meanings, and the typed scope- denial body.
Try it live
The Markdown reference pages in the sidebar carry copy-paste curl examples for every endpoint. A Postman collection covering the public surface is on the roadmap; until then, the curl examples are the canonical try-it-now path.
If you spot a discrepancy between these docs and what the API actually returns, please open an issue — the deployed behaviour is the source of truth and the docs should match.