What do common API errors mean?
A reference for HTTP status codes you might encounter when calling the Nozzle API, and how to fix them.
This guide explains the HTTP status codes you might see when calling the Nozzle API, what causes each one, and how to fix it.
For the basics of authenticating with the API and finding your IDs, see How do I authenticate with the Nozzle API?
Quick reference
| Status | Meaning | Most common cause |
|---|---|---|
400 Bad Request |
The request was malformed | Missing required field, invalid localeId, malformed JSON |
403 Forbidden |
Catch-all for auth and access issues | Bad or missing token, wrong workspaceId, or nonexistent resource |
404 Not Found |
Real resource ID paired with the wrong workspaceId |
Cross-workspace ID mix-up |
409 Conflict |
The request conflicts with current state | Usually DELETE on a resource with dependencies |
500–504 |
Server error | Transient infrastructure issue — usually retryable |
400 Bad Request
The server understood your request but rejected it because something in the body or URL is invalid.
Common causes:
- Missing a required field in the request body (e.g., a
PUT /keywordSources/{id}withoutversionId) - A
localeId,brandId, or other reference that doesn't exist in your workspace - Malformed JSON — a missing comma, unclosed bracket, or trailing comma in the request body
- A
(criteria_id, language)combination that doesn't have alocaleIdin Nozzle's catalog yet (see How do Nozzle locales work?) - Invalid
rrulestring in a schedule
How to fix:
- Validate the JSON body before sending — most languages have a built-in JSON parser that'll catch syntax errors
- Compare your request body against a known-good example (e.g., the
PUTexample in How do keyword sources work?) - If the response includes an error message, read it carefully — it usually points at the offending field
403 Forbidden
The most common error you'll encounter. Nozzle's API returns 403 for both authentication failures and resource access issues, rather than distinguishing them with separate 401 and 403 codes. If you see a 403, work through the possibilities in order:
Authentication issues:
- Missing
Authorizationheader entirely - Header format wrong — should be
Authorization: Token <your_api_key>(note the word "Token" and a space; not "Bearer") - API key is wrong, expired, or has been rotated
- Extra whitespace or a truncated key
Resource access issues:
- The
workspaceIdin your request doesn't match the workspace your API key was issued for - You're trying to access a keyword source, team, or other resource that lives in a different workspace
- The resource ID you're referencing doesn't exist (Nozzle returns
403rather than404for missing resources, to avoid leaking which IDs are valid)
How to fix:
- Verify the header format exactly:
Authorization: Token <your_api_key> - Confirm your API key is current and hasn't been rotated. If in doubt, create a new one.
- Verify the
workspaceId,teamId, andkeywordSourceIdin your request all belong to the same workspace - Double-check IDs against the URL of the resource in app.nozzle.io
404 Not Found
Returned in a specific scenario: when you provide a real keyword source ID paired with a workspaceId that doesn't own that resource. For most other "resource doesn't exist" cases, Nozzle returns 403 instead (see above).
Common causes:
- Copy-paste error: correct keyword source ID but wrong
workspaceId - You have access to multiple workspaces and are referencing IDs from different ones in the same request
- The resource was moved or the workspace was reorganized
How to fix:
- Verify the
workspaceIdmatches the workspace that owns the keyword source - Cross-check IDs in the URL of app.nozzle.io — the workspaceId and keyword source ID both appear in the app URLs
- If the response body includes a database error message (e.g.,
sql: no rows in result set), that's a signal the API couldn't find the specific resource-plus-scope combination you requested
409 Conflict
Your request conflicts with the current state of the resource. The server is refusing to apply the change to prevent data loss or inconsistency.
In practice, 409 responses on Nozzle's API are uncommon and typically limited to DELETE operations against resources with dependencies (see below). If you encounter a 409 on a PUT or POST request, contact us with the request details so we can investigate.
On DELETE requests
409 Conflict on DELETE usually means the resource is in a state that prevents deletion — for example, an in-progress operation, a dependent resource that needs to be removed first, or a transient lock.
How to fix:
- Wait briefly and retry (transient locks usually clear within seconds)
- Verify there are no dependent resources (e.g., a project may need its keyword sources removed before it can be deleted)
- If you're seeing repeated
409s on bulk deletes, reach out — we can often help clean up server-side faster than retrying
429 Too Many Requests
Nozzle doesn't currently enforce explicit per-customer rate limits, but well-designed API integrations should plan for them anyway in case that changes. If you start seeing 429 responses in the future, the standard patterns apply: implement exponential backoff, batch requests where you can (e.g., update many phrases in a single PUT instead of calling PUT once per phrase), and contact us if you're consistently hitting limits that block your integration.
500–504 Server errors
Something went wrong on Nozzle's end. These are usually transient.
How to fix:
- Retry the request after a short delay (usually a few seconds is enough)
- If a request consistently returns
500or higher across multiple retries, the request itself may be triggering a server bug — contact us with the request details (URL, body, time of request) so we can investigate - Build retry logic into any production integration — transient server errors happen with any API
It worked, but the result wasn't what I expected
Not all problems show up as error codes. A few patterns to watch for:
- A
PUTseems to have created a new keyword source instead of updating the existing one. Check that you sent the correctidin the URL path.PUTrequires the full object in the body — if you sent an object that mismatched the URL id, the API may not have applied the update where you expected. - Phrases I expected to be removed are still tracked. Remember that
PUT /keywordSources/{id}requires the full object — if you sent a partial body, missing fields may have been preserved as-is rather than removed. Always GET the full object, modify it, and PUT it back. - Devices or locales seem to have been multiplied unexpectedly. In a
basickeyword source, every phrase is tracked against every locale and device. If you have 10 phrases × 4 locales × 2 devices, you'll get 80 keyword combinations. For per-phrase targeting, use ajsonkeyword source.
Need help?
If you're hitting an error that isn't covered here — or one that's covered here but isn't behaving the way the doc describes — reach out with the request URL, request body (redact your API key), and the response status and body. We'd rather work through it with you than have you stuck.