Scoped API tokens, idempotent writes, unified webhooks, and full governance control over QR codes, short links, and physical asset lifecycle — all in one REST API.
Each token carries exactly the permissions it needs. 18 fine-grained scopes across assets, governance, lifecycle, crisis, and webhooks.
Send an Idempotency-Key header and POST safely — duplicate requests within 24 h return the cached response without creating duplicates.
20 event types, one subscription model. HMAC-SHA256 signed payloads, automatic retries with exponential back-off (1 min → 5 min → 15 min → 1 h).
Lite 100 req/min · Pro 1 000 req/min · Scale 10 000 req/min · Enterprise 50 000 req/min. Limits surfaced in X-RateLimit-* response headers.
Lock tokens to specific IP ranges — individual IPs or CIDR blocks. Requests from unlisted IPs receive 403 before any scope check.
Machine-readable specs at /api/v1/openapi.json and /api/v2/openapi.json. Import into Postman, Insomnia, or any OpenAPI-compatible tool.
Make your first authenticated request in under 2 minutes.
Go to Admin → API Tokens, click New token, choose your scopes, and copy the plain-text token shown once.
Pass the token as a Bearer in the Authorization header.
curl https://frqr.app/api/v2/qr-codes \
-H "Authorization: Bearer frqr_pk_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Product A QR",
"type": "url",
"destination": "https://example.com/product-a"
}'
All v2 responses are wrapped in a data key. Errors include a machine-readable error code.
{
"data": {
"id": 42,
"slug": "abc123",
"scan_url": "https://frqr.app/q/abc123",
"destination": "https://example.com/product-a",
"type": "url",
"created_at": "2026-05-06T12:00:00Z"
}
}
Grant only the scopes your integration needs — principle of least privilege.
| Scope | Grants access to |
|---|---|
assets:read
|
GET QR codes, short links, bio pages |
assets:write
|
POST/PATCH QR codes, short links, bio pages |
assets:delete
|
DELETE QR codes, short links, bio pages |
change_requests:read
|
List and view change requests |
change_requests:write
|
Submit new destination change requests |
change_requests:approve
|
Approve, reject, or emergency-override change requests |
custodians:read
|
View custodian assignments |
custodians:write
|
Assign and remove custodians |
batches:read
|
List asset batches |
batches:write
|
Create batches |
batches:recall
|
Trigger batch recall |
lifecycle:read
|
View lifecycle history and current state |
lifecycle:write
|
Transition asset lifecycle state |
crisis:read
|
View active crisis modes |
crisis:write
|
Activate or resolve crisis mode |
webhooks:manage
|
Create, update, delete webhook subscriptions |
tokens:read
|
List own API tokens |
tokens:write
|
Create and revoke own API tokens |
Subscribe to platform events and receive real-time HTTP callbacks to your endpoint.
POST /api/v2/webhooks
Authorization: Bearer frqr_pk_...
{
"url": "https://yourapp.com/hooks/frqr",
"events": [
"change_request.approved",
"asset.lifecycle.transitioned"
]
}
// X-Frqr-Signature: sha256=<hmac>
$sig = 'sha256=' . hash_hmac(
'sha256',
$rawBody,
$webhookSecret
);
$valid = hash_equals($sig, $header);
change_request.created
change_request.approved
change_request.rejected
change_request.emergency_approved
qr_code.created
qr_code.updated
qr_code.deleted
short_link.created
short_link.updated
short_link.deleted
asset.health.degraded
asset.health.recovered
asset.health.fallback.triggered
asset.lifecycle.transitioned
batch.recalled
crisis.activated
crisis.resolved
Limits apply per token per minute. Response headers tell you where you stand.
| Plan | Requests / min | Max tokens |
|---|---|---|
| Lite | 100 | 5 |
| Pro | 1,000 | 20 |
| Scale | 10,000 | Unlimited |
| Enterprise | 50,000 | Unlimited |
Both versions coexist — v1 is maintained for backward compatibility, v2 is the recommended path for new integrations.
Safe retries on any POST or PATCH request — send the same key within 24 hours to get the same response.
curl -X POST https://frqr.app/api/v2/qr-codes \
-H "Authorization: Bearer frqr_pk_..." \
-H "Idempotency-Key: order-9823-qr-create" \
-H "Content-Type: application/json" \
-d '{ "name": "Order 9823 QR", "type": "url", "destination": "https://track.example.com/9823" }'
A cached hit returns HTTP 200 with X-Idempotent-Replayed: true. Keys are namespaced per user — you cannot replay another user's key.
Create your first token and make a request in under 2 minutes.