Base URLs
Credential model
There are no separate live and test keys: every key belongs to one organization.
Send server credentials as a Bearer token:
sk_.
Key permissions
A secret key can be limited to read or write access per resource, for examplecredit_system:read or plan:write. A key without the permission a route needs gets 403.
- Permissions restrict a key only when your organization has the API key permissions feature. On other organizations, creating a key with permissions is refused with
premium_integration_missinginstead of storing permissions that would not apply. A key created without permissions has full access. - Rotating a key gives the new key the same permissions as the old one.
- Plan transition policies have their own resource,
plan_transition_policy. Keys that existed before it have the same access to it that they have toplan. - Check credit usage needs
credit_system:readand Track and consume credits needscredit_system:write. - Set a key’s permissions in the dashboard under Developers > API keys, when you create a secret key or with Edit. The read and write picker shows only for secret keys on organizations with API key permissions. With API key permissions, a secret key with read and write on every resource is labelled Full access, and any other key Restricted with its grants, for example Restricted · plan: read. On other organizations, every secret key is labelled Full access (permissions not enforced on this plan). A publishable key is labelled Plan catalog · read only.
Engine routes
On organizations with API key permissions, these Engine routes check the key too. A key without the permission gets403 with code: permission_denied and the message API key requires <resource>:<mode> permission. Organizations without API key permissions see no change.
POST /analytics/snapshot and POST /onboarding/chat are internal to Nozle. They accept only Nozle’s internal service token, and a secret key gets 403 with internal service authentication required.
Browser access (CORS)
The publishable-key plan catalog,GET /plans and GET /plans/{code} on the Engine, answers CORS from any origin, so the React components can load plans on your own site. The catalog and its preflight return Access-Control-Allow-Origin: * and Access-Control-Allow-Methods: GET, OPTIONS, never Access-Control-Allow-Credentials. Every other route answers only the origins Nozle allows, so call them from your backend.
Public authentication endpoints
These are Core routes, for examplehttps://api.nozle.app/core/api/v1/auth/send-otp. The Engine does not serve them.
POST /api/v1/auth/send-otpPOST /api/v1/auth/verify-otpPOST /api/v1/auth/signup
send-otp(email) answers200with{"success": true, "expiresIn": 300}. A new email receives a 6-digit code that is valid for 5 minutes; an email that already has an account receives a login email instead of a code. A second request for the same email within 60 seconds, or more than 10 requests from one IP address in an hour, answers429withretryAfterin seconds.verify-otp(email,code) answers200with{"verified": true, "verificationToken": "..."}, whichsignupaccepts for 10 minutes. A wrong, expired or missing code answers401with{"error": "invalid code"}. Before, an expired code answered410: treat401as “invalid or expired, request a new code”. A code that is not 6 digits answers400.- Each email has 5 attempts per 15 minutes, and each IP address 20 per hour. Requesting a new code does not reset the attempts. Past the limit,
verify-otpanswers429withtoo many attempts, try again later.