Skip to main content

Errors

The Sunset API uses conventional HTTP status codes and returns structured error responses. Every error response includes an X-Request-Id header for debugging.

HTTP Status Codes

CodeMeaning
200OK - Request succeeded
201Created - Resource created successfully
204No Content - Resource deleted successfully
304Not Modified - Resource unchanged (ETag matched via If-None-Match)
400Bad Request - Malformed request syntax
403Forbidden - You don’t have access to this resource
404Not Found - Resource does not exist
409Conflict - Duplicate idempotency key with different request body
412Precondition Failed - Resource modified since ETag (via If-Match)
422Unprocessable Entity - Validation errors in the request body
429Too Many Requests - Rate limit exceeded
500Internal Server Error - Something went wrong on our end

Error Response Format

All error responses follow this structure:
{
  "error": {
    "code": "validation_error",
    "message": "The request body contains invalid fields.",
    "details": [
      {
        "field": "email",
        "message": "Must be a valid email address."
      },
      {
        "field": "date_of_birth",
        "message": "Must be a valid date in YYYY-MM-DD format."
      }
    ]
  }
}

Error Codes

CodeHTTP StatusDescription
forbidden403You don’t have permission to access this resource.
not_found404The requested resource was not found.
idempotency_conflict409A different request body was sent with the same Idempotency-Key.
precondition_failed412The resource has been modified since the provided ETag. Re-fetch and retry.
validation_error422The request body failed validation. Check the details array.
rate_limit_exceeded429You’ve exceeded the rate limit. Retry after the X-RateLimit-Reset time.
internal_error500An unexpected error occurred. Contact support if it persists.

PATCH Semantics (JSON Merge Patch)

All PATCH endpoints use JSON Merge Patch semantics (RFC 7396):
  • Only include the fields you want to change.
  • Fields set to null are removed (set to null on the resource).
  • Fields not included in the request body are left unchanged.
  • Nested objects are merged recursively.
# Only updates the estate_value field; all other fields remain unchanged
curl -X PATCH "https://api.example.com/v1/cases/CASE_ID" \
  -H "Content-Type: application/json" \
  -d '{ "estate_value": "over_150000" }'

Handling Errors

import requests

response = requests.get(
    "https://api.example.com/v1/cases/invalid-id",
    headers={}
)

if response.status_code == 404:
    error = response.json()["error"]
    print(f"Error: {error['message']}")
elif response.status_code == 422:
    error = response.json()["error"]
    for detail in error.get("details", []):
        print(f"Field '{detail['field']}': {detail['message']}")
elif response.status_code == 429:
    reset_time = response.headers.get("X-RateLimit-Reset")
    print(f"Rate limited. Retry after timestamp: {reset_time}")
elif response.status_code == 412:
    # Re-fetch the resource and retry with the new ETag
    print("Resource was modified. Re-fetch and retry.")

# Always log the request ID for debugging
request_id = response.headers.get("X-Request-Id")
print(f"Request ID: {request_id}")