Developer surface

API access for agencies, automations, and serious operators

Every dashboard workflow is backed by a JSON API on https://api.qrscan.ink/api. Production sessions start through passwordless sign-in plus rCAPTCHA protection.

Core endpoints

  • GET /api/templates
  • GET /api/qr-links/check-slug?slug=MapleRestaurant
  • POST /api/businesses
  • POST /api/qr-links
  • POST /api/menus/from-template
  • POST /api/landing-pages/from-template
  • POST /api/bulk/qr-links/preview
  • POST /api/bulk/qr-links/import
  • GET /api/exports/bundles

Grand platform endpoints

  • GET /api/analytics
  • GET /api/analytics/summary
  • GET /api/analytics/aggregate?group_by=device
  • GET /api/integration-guides
  • GET /api/integration-credentials
  • POST /api/integration-credentials
  • PATCH /api/integration-credentials/{id}
  • DELETE /api/integration-credentials/{id}
  • POST /api/integrations/{key}/test
  • POST /api/integrations/{key}/sample-event
  • GET /api/integration-deliveries
  • POST /api/integration-deliveries/{id}/retry
  • GET /api/integration-recipes
  • POST /api/integration-recipes/{key}/install
  • POST /api/workflows/restaurant-launch
  • POST /api/workflows/product-passport-launch
  • POST /api/workflows/agency-client-launch
  • GET /api/pricing-policy
  • POST /api/campaigns
  • POST /api/wallet-passes
  • POST /api/product-passports
  • POST /api/product-passports/bulk-import
  • POST /api/product-passports/{id}/recall-notice
  • PATCH /api/product-passports/{id}/resolver-links
  • POST /api/table-qr-packs
  • POST /api/restaurant/tables
  • POST /api/restaurant/service-requests
  • POST /api/restaurant/order-intents
  • GET /api/restaurant/kitchen-queue
  • POST /api/restaurant/meal-periods
  • POST /api/assets
  • POST /api/team-invites
  • POST /api/client-spaces
  • GET /api/notifications
  • GET /api/push/config
  • GET /api/push/subscriptions
  • POST /api/push/subscriptions
  • POST /api/push/test
  • PATCH /api/notification-preferences
  • POST /api/widget/config
  • GET /api/widget/config
  • POST /api/widget/lead
  • GET /api/custom-domains/{id}/health
  • GET /api/reports/{id}/preview
  • POST /api/reports/schedules/{id}/send-test
  • POST /api/scan-notification-preferences
  • GET /api/qr-links/{id}/safety-report
  • POST /api/api-tokens
  • POST /api/mcp-tokens

AI endpoints

  • GET /api/ai/summary
  • POST /api/ai/menu-import
  • GET /api/ai/menu-imports
  • PATCH /api/ai/menu-imports/{id}
  • POST /api/ai/menu-imports/{id}/approve
  • POST /api/ai/analyze-link
  • POST /api/ai/destination-rewrite
  • POST /api/ai/translate
  • POST /api/ai/monthly-report
  • POST /api/ai/accessibility-review
  • POST /api/ai/seo-metadata
  • POST /api/ai/experiment-suggestions
  • POST /api/ai-tasks

Admin endpoints

  • GET /api/admin/credential-health
  • GET /api/admin/audit-logs
  • GET /api/admin/abuse-queue
  • POST /api/admin/qr-links/{id}/safety-scan
  • POST /api/admin/qr-links/{id}/pause
  • POST /api/admin/qr-links/{id}/restore
  • GET /api/admin/deploy-health

Create a redirect QR link

curl -X POST https://api.qrscan.ink/api/qr-links \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"business_id":1,"name":"Main menu","slug":"MapleRestaurant","mode":"redirect","redirect_url":"https://example.com/menu"}'

Authentication and scopes

Production browser sessions begin with passwordless sign-in plus rCAPTCHA protection. Automation uses API or MCP bearer tokens. Tokens can be limited by scope, business id, expiration, revocation, and per-minute rate.

Rate limits

Named throttles protect auth, public forms, rCAPTCHA, QR redirects, user API calls, token calls, MCP, AI, admin writes, exports, and webhook tests. A 429 response means retry after the standard Laravel rate-limit reset window.

Pagination

Growing list responses return Laravel paginator objects under their resource key, such as {"qr_links":{"data":[],"current_page":1,"per_page":25,"total":0}}. Use ?per_page=1..100.

Error shape

Validation, auth, authorization, and throttling responses use constant JSON envelopes with message and, for validation, errors. Treat 401, 403, 422, and 429 as non-retryable except rate limits.

Public rCAPTCHA flow

Public lead forms must call POST /api/public/rcaptcha/challenge, verify with POST /api/public/rcaptcha/verify, and submit the returned one-use token to POST /api/public/lead-submissions.

Webhook safety

Webhook targets must be HTTPS public hosts. Deliveries include X-QRScanInk-Timestamp and X-QRScanInk-Signature, an HMAC over timestamp.payload. Reject timestamps outside a five-minute replay window.

Bulk import and export caps

CSV import preview validates headers, reserved slugs, duplicate slugs, and HTTPS destinations before save. Exports return clear caps through GET /api/exports/bundles.

Client-owned integrations

GET /api/integration-guides returns help URLs and client fields for self-serve setup. /api/integration-credentials stores business-scoped credentials, masks values after write, and never returns full secrets.

Integration delivery logs

POST /api/integrations/{key}/sample-event sends or records test scan, lead, conversion, service request, order intent, report, recall, product passport, and widget lead payloads. Delivery logs are redacted and retryable.

Launch-depth endpoints

WalletCard exports use GET /api/wallet-passes/{id}/export?format=vcf|ics|html|apple|google. GS1 workflows use POST /api/gs1/validate, GET /api/product-passports/{id}/exports, POST /api/product-passports/{id}/recall-override, and GET /api/product-passports/{id}/analytics. Restaurant request-only operations use public rCAPTCHA-protected service/order endpoints plus GET /api/restaurant/order-intents/{id}/ticket, POST /api/restaurant/order-intents/{id}/advance, and GET /api/restaurant/pos-handoff. Team handoff uses POST /api/team-invites/accept; agency proof uses POST /api/reports/bundles.

Machine-readable contract

The practical OpenAPI-style contract is published at /openapi.json and documents public, auth, core, admin, AI, and MCP endpoint groups.