How do I get an API key?
Every API call carries the tenant's key in an HTTP header:
Authorization: Bearer lpdc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
There is no login step and no separate token to obtain: the key goes on every request.
Never put the key in the URL. A key in a query string ends up in server logs, in intermediate proxy logs and in browser history. Header only.
- An organisation can hold several active keys at once, which is how you rotate one with no downtime: issue the new one, update the callers, revoke the old one.
- Every key expires. Pick a duration when you issue it — 30, 90, 180, 365 or 730 days, 90 by default — and there is no unlimited option and no grace period after it: an expired key answers exactly like a revoked one. Issue the next key before the old one runs out.
- Revocation takes effect immediately — the very next request
gets
INVALID_API_KEY. There is no grace window. - A key carries scopes: what it may be used for, chosen when
it is issued, one permission at a time, with a checkbox for each (compose,
read, download, manage templates, send for signature, the one-call flow,
bulk jobs, usage, test calls), and never widened afterward — a key's permissions only ever
shrink. Calling something outside its scope answers
TOKEN_SCOPE_NOT_ALLOWED; issue a new, wider key rather than trying to edit the old one. - A key has a name, which is required and different from the name of every other live key of your organisation (billing-export, crm-sync); the name of a revoked key can be used again. Keys are issued only in the console, on the API keys page: never by us on your behalf.
- Keys are stored only as hashes. Not even an administrator can read an issued key back — the console shows only its last four characters, to tell several open keys apart.
The starter key
A new account is handed a starter key, named
hello-world, instead of a full-access one. It holds exactly what the
first call needs: documents:compose, documents:read,
documents:download, usage:* and isTest (the
sandbox). It cannot manage templates, send for signature, run the flow or submit a
bulk job, and it expires after a short time (90 days unless we have changed it).
A coordinator creates a full key in one click on the
API keys page of the console; nothing about an existing key changes when you do. Calling something
the starter key does not hold answers TOKEN_SCOPE_NOT_ALLOWED and
names the missing scope in details.missingScopes.
Which scope each call needs
A key must hold a scope of the call's group, and the specific scope
for the call; the group scope (documents:*, signatures:*,
bulk:*) satisfies every call of its group. A refusal lists the scope
you were missing. A bulk submit needs two: bulk:submit runs the batch and the
single call’s scope (documents:compose, signatures:ses or flow:*) authorises what is
done in it, so a batch is never a way round a scope. With both missing the answer names the first,
bulk:submit; once that is granted it names the other.
| Call | Scope |
|---|---|
POST /api/v1/compose/documents/generate | documents:compose |
POST /api/v1/compose/documents/validate | documents:compose |
GET /api/v1/compose/documents/{id} (the PDF), /api/v1/compose/documents/{id}/download-links | documents:download |
POST or DELETE /api/v1/compose/files | documents:compose |
GET /api/v1/compose/files | documents:read |
/api/v1/compose/templates/* | documents:templates |
/api/v1/sign/* | signatures:ses |
POST /api/v1/bulk/compose | bulk:submit and documents:compose |
POST /api/v1/bulk/sign | bulk:submit and signatures:ses |
POST /api/v1/bulk/flow | bulk:submit and flow:* |
POST /api/v1/bulk/files, cancel or retry a job | bulk:submit (a retry also needs the scope of the job’s operation) |
GET /api/v1/bulk/jobs* | bulk:read |
/api/v1/flow/* | flow:* |
GET /api/v1/usage, GET /api/v1/callback-environments | none: readable by any live key |
A request with "isTest": true | isTest, on top of the above |
Expiry notices
We email the organisation's coordinators once at 30, 7 and 1 day before a key expires, with the exact date and a link to create the next one. A key whose whole life is no longer than a threshold skips it. There is no grace period: at the stated second the key stops working.
A limit for one key
Besides the organisation's requests-per-minute limit, a coordinator can give a
single key its own, on the API keys page. A key over its limit is refused with
RATE_LIMIT_EXCEEDED (HTTP 429, the usual Retry-After and
X-RateLimit-* headers, and details.limitedBy: "token")
before the request counts against the organisation, so one broken
integration cannot use up the rest. The organisation's limit still applies to
every key. With no limit set the key follows a platform default, which is none.
What a key may call
The suite is three products, sold separately, and an organisation may hold any combination of them:
| Surface | Prefix | Also answers on |
|---|---|---|
| Composer Fly — document composition | /api/v1/compose/* | /api/v1/documents/*/api/v1/templates/* |
| Signer Fly — electronic signature | /api/v1/sign/* | /api/v1/signatures/* |
| Document Fly — the one-call flow | /api/v1/flow/* | — |
One prefix per product, since 2026-09-19. The three
surfaces are the three products as they are sold and switched, so the URL
now says which one you are calling. Everything under a prefix belongs to
that product: /api/v1/compose/documents/generate,
/api/v1/compose/templates,
/api/v1/sign/envelopes.
The previous paths still work and are not going away on a
date we have not told you. If your integration calls
/api/v1/documents/generate, it keeps working exactly as it
did — same request, same response, same organisation switch governing it.
The new spelling is what this guide documents and what the service hands
back in its own responses (a flow's document.url, for
instance); moving across is a change of string and nothing else. If we
ever do retire the old prefixes, it will be announced with a date and a
notice period, not discovered.
A call to one that is not active answers 403
SUITE_NOT_ENABLED, names it in details.suite and lists
what you do have in details.enabled. Nothing is charged for it, and
no key change will fix it — it is a subscription, not a credential. A
coordinator can see the same list under Settings in their own console.
The switches govern doors, not capabilities. A flow
composes a document internally whether or not the composition API is on for
you — you are calling the flow, not the composition API. But its answer links
to /api/v1/compose/documents/{id} and to the envelope's own download, so
with only the flow active those links answer SUITE_NOT_ENABLED.
If you need to fetch what a flow produced, you need the surface it lives
on.
It applies to API keys only. Your console is unaffected: templates, documents and signatures stay visible there whatever is switched off here.