Authentication
Every API request must be authenticated with your API key. Pass the
key in the Authorization header using the Basic scheme, with the key (including its
key- prefix) as the credential:
Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Unlike standard HTTP Basic auth, you send the raw API key — not a base64-encoded
user:password string. Just put Basic followed by your key-... value.
Example request
curl https://api.prolinksqr.com/links \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
For requests with a body, also set the content type:
curl -X POST https://api.prolinksqr.com/folders \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Campaigns" }'
Scopes and permissions
Each endpoint requires a specific scope. A request succeeds only if your key includes
that scope (or the catch-all all scope). This table maps every API-key endpoint to
its required scope:
| Method & path | Required scope |
|---|---|
GET /links, GET /links/:id | links.read |
POST /links | links.create |
PUT /links/:id, PATCH /links/:id | links.update |
POST /links/:id/favorite, DELETE /links/:id/favorite | links.update |
DELETE /links/:id, POST /links/:id/archive | links.delete |
POST /links/:id/pause | links.pause |
POST /links/:id/resume | links.resume |
POST /links/:id/duplicate | links.create |
POST /links/:id/save-template | templates.create |
GET /links/:id/analytics/*, POST /links/:id/analytics/export | — (any valid key) |
GET /analytics/*, POST /analytics/export | — (any valid key) |
GET /folders, GET /folders/:id | folders.read |
POST /folders | folders.create |
PUT /folders/:id | folders.update |
DELETE /folders/:id | folders.delete |
GET /templates, GET /templates/:id | templates.read |
POST /templates | templates.create |
PUT /templates/:id | templates.update |
DELETE /templates/:id | templates.delete |
POST /bulk-generate | bulk.create |
GET /cafes, GET /cafes/:id (and nested reads) | cafe.read |
POST /cafes | cafe.create |
PUT /cafes/:id (and nested writes, incl. deleting categories and items) | cafe.update |
DELETE /cafes/:id, DELETE /cafes/:id/groups/:groupId | cafe.delete |
Endpoints marked any valid key (the analytics endpoints) require authentication but no specific scope — every active key can call them.
Some endpoints also require your account to be on a specific plan (e.g. API key
management itself is unavailable on the starter and enterprise plans). A
plan-restricted request currently comes back as 401, not 403, even though the key
itself is valid and correctly scoped — see the error table below.
Auth errors
| Status | Cause |
|---|---|
401 | Missing Authorization header, malformed key, the key is inactive/deleted/expired, or your account's plan doesn't allow the endpoint. |
403 | The key is valid but does not include the scope the endpoint requires. |
{ "message": "You do not have permission to perform this action." }
An expired key (see Creating an API Key) is deactivated by a periodic background job, not instantly at the expiration timestamp — so a request may still briefly succeed with a key that has technically expired.
Keeping keys safe
- Treat API keys like passwords. Never commit them to source control or expose them in client-side code.
- Use a separate key per integration so you can revoke one without affecting others.
- Rotate keys periodically: create a new key, switch your integration over, then delete the old one.