HTTP API
Base URL: https://api.rerunlab.com/v1. Authenticate with Authorization: Bearer YOUR_KEY. Obtain a key from the workspace owner. Download the machine-readable contract at /openapi.yaml.
Create a watch
First GET /projects to obtain a project ID. POST /watches requires an Idempotency-Key. Retrying identical input with the same key for 24 hours returns the original result; changed input returns idempotency_conflict.
curl https://api.rerunlab.com/v1/watches \
-H "Authorization: Bearer $RERUNLAB_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: my-job-123-watch' \
--data '{"project_id":"prj_YOUR_PROJECT","name":"Job 123 completed","source":{"url":"https://api.example.com/jobs/123"},"selector":"/status","trigger":{"type":"condition","operator":"eq","value":"completed","fire_on_initial_match":true,"stop_after_match":true},"interval_seconds":600,"metadata":{"job_id":"123"}}'
Watches and previews
GET /watches supports project_id, state, health, limit and cursor. GET /watches/:id returns version. PATCH requires If-Match with that exact version. Unknown write fields are rejected. POST /watches/:id/pause, /resume, /restart and /check change lifecycle or request a check. Restart accepts a new expires_at. DELETE soft-deletes and fences in-flight work. POST /watches/preview accepts a watch configuration and performs one charged observation without changing any baseline.
Events and deliveries
GET /events accepts cursor, limit (1–100), project_id, watch_id, type and start=latest. Persist next_cursor after processing data. Cursors bind the workspace and filters. has_more means call again immediately; otherwise wait at least five seconds. A 410 cursor_expired means retained history has a gap: deliberately restart from the oldest retained history or from latest. Concurrent readers are independent. GET /events/:id retrieves one retained event.
GET /deliveries and /deliveries/:id expose attempt outcomes. POST /deliveries/:id/replay requires deliveries:replay and an Idempotency-Key. Replay preserves the original event ID and destination revision, and requires 24 hours of remaining event retention.
Credentials, destinations and usage
POST /credentials accepts project_id, name, origin, kind (bearer or api_key), header_name for api_key, and value. PATCH rotates its value and resets dependent watch baselines. DELETE requires disable_watches=true if referenced. Values are write-only.
POST /endpoints accepts project_id, name, url. Its signing_secret is returned once. POST /endpoints/:id/verify performs the nonce challenge. PATCH with url creates a new unverified revision. POST /endpoints/:id/rotate-secret rotates the current signing secret; /test sends a labeled synthetic event. DELETE cancels pending deliveries. GET /usage reports admitted checks, remaining checks, reset time, watch counts and limits.
Errors and rate limits
Errors have error.code, error.message, error.details and request_id. Typical codes: validation_failed (422), unauthorized (401), forbidden (403), not_found (404), version_conflict and idempotency_conflict (409), cursor_expired (410), rate_limited or quota_exhausted (429), polling_unavailable (503). Honor Retry-After, preserve cursors on errors, and use exponential backoff with jitter for transient failures. Read operations are limited to 120 requests per minute per key/workspace, with an additional IP cap. Manual checks: one per watch per 60 seconds. Preview: five per workspace per minute.