# Errors & Error Handling Synapse uses standard HTTP status codes with a consistent error response format. This page explains how to interpret and recover from errors. ## Error Response Format All errors return JSON with this structure: ```json { "statusCode": 401, "error": "Unauthorized", "message": "Mind Key fehlt oder ungültig.", "docs": "https://synapse.schaefer.zone/docs/getting-started/authentication" } ``` | Field | Description | |-------|-------------| | `statusCode` | HTTP status code | | `error` | HTTP status name | | `message` | Human-readable error description | | `docs` | URL to relevant documentation (when applicable) | ## HTTP Status Codes ### 200 OK Success. The request was processed correctly. ### 201 Created Success. A new resource was created (e.g. `POST /memory`). ### 204 No Content Success. No body returned (e.g. `DELETE /memory/:id`). ### 400 Bad Request The request was malformed. Common causes: - Missing required JSON fields - Invalid JSON syntax - Invalid enum value (e.g. wrong category) ```json { "statusCode": 400, "error": "Bad Request", "message": "category must be one of: identity, preference, fact, project, skill, mistake, context, note, credentials" } ``` **Fix:** Check the request body against the API docs. Ensure all required fields are present and have valid values. ### 401 Unauthorized Authentication failed. Common causes: - Missing `Authorization` header - Invalid Mind Key or JWT - Using a Mind Key where a JWT is required (or vice versa) ```json { "statusCode": 401, "error": "Unauthorized", "message": "Mind Key fehlt oder ungültig.", "docs": "https://synapse.schaefer.zone/docs/getting-started/authentication" } ``` **Fix:** Verify your token. See [Authentication](/docs/getting-started/authentication). ### 403 Forbidden You're authenticated but not allowed to perform this action. Common causes: - Trying to delete another user's mind - Trying to verify a memory with a Mind Key (requires JWT) - Mind is disabled **Fix:** Check if you're using the correct token type for this endpoint. ### 404 Not Found The requested path or resource doesn't exist. > [!CRITICAL] > **Do NOT guess endpoint paths.** Only the paths listed in `GET /endpoints` > exist. If you get a 404, you used a wrong path. ```json { "statusCode": 404, "error": "Not Found", "message": "Route GET /memory/list not found", "docs": "https://synapse.schaefer.zone/docs/api/errors" } ``` **Fix:** Call `GET /endpoints` to see the list of valid endpoints. Compare your URL against the list character-by-character. ### 409 Conflict The request conflicts with existing state. Common causes: - Trying to register with an email that already exists - Duplicate webhook URL **Fix:** Use a different value, or use `PUT` to update the existing resource. ### 429 Too Many Requests You hit a rate limit. Only applies to `?key=` query parameter auth (60/min). ```json { "statusCode": 429, "error": "Too Many Requests", "message": "Rate limit exceeded. Use Authorization header for unlimited access." } ``` Response headers: ``` X-RateLimit-Limit: 60 X-RateLimit-Remaining: 0 Retry-After: 42 ``` **Fix:** Switch to `Authorization: Bearer` header (no rate limit), or wait `Retry-After` seconds. ### 500 Internal Server Error Server error. This shouldn't happen — if it does, it's a bug. **Fix:** 1. Retry with exponential backoff (1s, 2s, 4s, 8s) 2. Check `GET /health` to see if the server is up 3. If persistent, report the error ### 503 Service Unavailable Server is temporarily down (e.g. during deployment, database migration). **Fix:** Wait and retry. Check `GET /health`. ## Recovery Patterns ### Retry with exponential backoff ```python import time import requests def call_with_retry(url, max_retries=3): for attempt in range(max_retries): try: r = requests.get(url, headers={"Authorization": f"Bearer {KEY}"}) if r.status_code == 429: wait = int(r.headers.get("Retry-After", 60)) time.sleep(wait) continue if r.status_code >= 500: time.sleep(2 ** attempt) continue return r except requests.RequestException: time.sleep(2 ** attempt) raise Exception(f"Failed after {max_retries} retries") ``` ### Auth error handling ```python def safe_call(url, key): r = requests.get(url, headers={"Authorization": f"Bearer {key}"}) if r.status_code == 401: # Mind Key invalid — alert user raise AuthError("Mind Key invalid or expired") return r ``` ## Common Error Scenarios ### "Mind Key fehlt oder ungültig" - You forgot the `Authorization` header - You used `?key=` but the key is wrong - You're using a JWT where a Mind Key is required ### "Route not found" - You guessed a path that doesn't exist - You used a verb wrong (e.g. `GET /memory` vs `POST /memory`) - Check `GET /endpoints` for valid paths ### "Rate limit exceeded" - You're using `?key=` and exceeded 60 req/min - Switch to `Authorization: Bearer` header ## Next Steps - [Authentication](/docs/getting-started/authentication) - [API Overview](/docs/api/overview) - [Rate Limits](/docs/api/rate-limits)