Skip to content

HTTP Endpoint Design

This guide covers how to design the HTTP endpoints that Recuro calls, ensuring they work reliably with retries, timeouts, and assertions.

Make endpoints idempotent

Recuro may call your endpoint more than once for the same logical operation — either through explicit retries (queue jobs) or if a cron fires while a previous execution is still in-flight. Design your endpoints to handle duplicate requests safely:

  • Use unique identifiers (order ID, event ID) to detect and skip duplicate processing
  • Use database transactions with INSERT ... ON CONFLICT or equivalent
  • Return the same successful response for duplicate requests

Return proper status codes

Your endpoint’s HTTP status code determines whether Recuro considers the execution successful:

CodeRecuro interpretation
200-299Success (subject to assertions)
400-499Failure — http_client_error
500-599Failure — http_server_error

Return 200 for successful processing. Return 500 (or appropriate error code) for genuine failures. Never return 200 when processing actually failed — this hides the failure from monitoring and alerting.

Handle timeouts gracefully

Recuro’s default timeout is 30 seconds (configurable up to 300). If your endpoint takes longer than the timeout, the connection is closed and the execution is marked as timeout.

To avoid timeout failures:

  • Respond quickly: Acknowledge the request and process asynchronously if the work takes more than a few seconds
  • Return early: Send a 202 Accepted response and process in the background
  • Increase the timeout: Set timeout_seconds on the cron or queue if the endpoint legitimately needs more time

Keep responses small

Recuro captures the full response body for debugging purposes. Large response bodies increase storage usage and slow down the dashboard. Return concise responses:

{ "status": "ok", "processed": 42 }

Avoid returning large data dumps, binary content, or full HTML pages.

Accept POST with JSON body

For endpoints receiving payloads from Recuro:

  • Accept Content-Type: application/json
  • Parse the JSON body from the request
  • Validate the expected fields

If your endpoint does not expect a body, use GET as the HTTP method.

Implement health check endpoints

For cron-based health checks, create a dedicated endpoint that:

  • Checks critical dependencies (database, cache, external APIs)
  • Returns a clear success/failure indicator in the response body
  • Responds within a few seconds (not the 30-second default timeout)

Good — clear, parseable, fast:

{ "healthy": true, "database": "ok", "cache": "ok" }

Bad — an HTML page that happens to return 200:

<html>...</html>

Combine with assertions to detect degradation:

{
"success_assertions": [
{ "type": "status_code_equals", "value": "200" },
{ "type": "json_path_equals", "value": "healthy=true" },
{ "type": "response_time_under_ms", "value": "3000" }
]
}

Next steps