Overview
Pinlyx Public API v1 (1.4.0)
Section titled “Pinlyx Public API v1 (1.4.0)”The Pinlyx Public API provides programmatic access to your contacts,
Telegram messaging, the social inbox and post scheduler, sales pipeline (deals),
tasks, finance (read-only) and the email inbox. All requests must include an
Authorization: Bearer <token>
header where the token is a Pinlyx API key in the format
csk_<env>_<keyId><secret>. Access is scope-based - each key is issued with a
specific set of scopes (e.g. contacts:read, telegram:send), and operations
that require a scope not granted to the key return 403 Forbidden. All responses
are JSON. Rate limits are per-key and communicated via X-RateLimit-Limit,
X-RateLimit-Remaining, and X-RateLimit-Reset response headers. An MCP server
for AI agent integration is available at the same host (POST /mcp).
Workspaces (X-Workspace-Id)
CRM data is shared inside a workspace. Send X-Workspace-Id: <id> on any CRM
request to act on that team’s shared pool; omit it and the key resolves your
default workspace, falling back to your personal data when you belong to none.
Membership is verified server-side on every request, so an id you are not a
member of silently falls back to personal scope instead of widening access.
GET /v1/me lists the workspaces a key may address and the role it holds in
each; a viewer role can read but every write returns 403.
Idempotent writes (Idempotency-Key)
Send Idempotency-Key: <your-unique-string> on POST /v1/contacts,
POST /v1/contacts/batch or PATCH /v1/contacts/{id} to make a retry safe.
The first call runs and its status code and body are stored for 24 hours; a
repeat of the same key returns that stored response verbatim with
Idempotency-Replayed: true, without touching your data. Reusing a key with a
different request body returns 409 - that is a client bug, not a retry.
Property casing
Property names inside a response object are PascalCase (Id, ExternalId,
CustomFields); only the pagination envelope keys (items, nextCursor,
hasMore) and the tag dictionary are camelCase. The schemas below spell
properties in camelCase for readability, so match them case-insensitively when
you generate a client. Request bodies are parsed case-insensitively, so either
casing is accepted on the way in.
Pagination
Every collection endpoint returns the same envelope:
{ "items": [...], "nextCursor": <cursor|null>, "hasMore": <bool> }. Pass the
returned nextCursor back as after (or before on message threads and the
conversation list) to fetch the next page. Endpoints whose result set is
naturally complete - connected accounts, pipeline boards, a contact’s tags -
still return the envelope with nextCursor: null and hasMore: false, so one
client loop works everywhere.
Plan-gated modules
A scope says what a key is allowed to do; the workspace’s plan says what the
workspace has. Modules that are not on every plan (the social inbox and the post
scheduler today) answer 402 with error: payment_required and the missing
feature key in details.FeatureKey when the plan lacks them. That is a permanent
answer for that workspace until it upgrades, so treat it as a configuration
problem rather than a transient failure and do not retry it.
- OpenAPI version: 3.0.3
Authentication
Section titled “ Authentication ”bearerAuth
Section titled “bearerAuth ”Pinlyx API key. Format: csk_<env>_<12-char-keyId><32-char-secret>. Obtain keys from the Pinlyx dashboard. Keep secret - the full token is never stored server-side (only a bcrypt hash of the secret portion).
Security scheme type: http
Bearer format: csk_<env>_<key>