Push Route picks and verdicts
const url = 'https://api.cedr.dev/v1/route/history';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"org":"northwind","records":[{"type":"pick","id":"p-1a2b3c4d5e6f","at":"2026-10-29T07:42:00Z","route":"review.code","rules":"8ff065e","target":"codex/gpt-6.1-sol","effort":"high","reason":"primary","state":"ready","size":"medium"},{"type":"verdict","id":"p-1a2b3c4d5e6f","at":"2026-10-29T08:10:00Z","verdict":"accepted"},{"type":"council","id":"c-1a2b3c4d5e6f","at":"2026-10-29T08:20:00Z","route":"review.council","run":"r-1a2b3c4d5e6f","round":1,"rounds":1,"gate":"block","next":"revise","quorum":2,"block":"P1","reviewers":["codex/gpt-6.1-sol","claude/claude-opus-5-5"],"groups":{"P0":0,"P1":1,"P2":0,"P3":2},"findings":{"codex/gpt-6.1-sol":2,"claude/claude-opus-5-5":1}}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.cedr.dev/v1/route/history \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "org": "northwind", "records": [ { "type": "pick", "id": "p-1a2b3c4d5e6f", "at": "2026-10-29T07:42:00Z", "route": "review.code", "rules": "8ff065e", "target": "codex/gpt-6.1-sol", "effort": "high", "reason": "primary", "state": "ready", "size": "medium" }, { "type": "verdict", "id": "p-1a2b3c4d5e6f", "at": "2026-10-29T08:10:00Z", "verdict": "accepted" }, { "type": "council", "id": "c-1a2b3c4d5e6f", "at": "2026-10-29T08:20:00Z", "route": "review.council", "run": "r-1a2b3c4d5e6f", "round": 1, "rounds": 1, "gate": "block", "next": "revise", "quorum": 2, "block": "P1", "reviewers": [ "codex/gpt-6.1-sol", "claude/claude-opus-5-5" ], "groups": { "P0": 0, "P1": 1, "P2": 0, "P3": 2 }, "findings": { "codex/gpt-6.1-sol": 2, "claude/claude-opus-5-5": 1 } } ] }'What cedr route sync sends: up to 500 history records from one machine, in order. Picks and council results are stored once per ID, so a retried batch is safe; a verdict lands only on your own pick and only when newer than the one it has. Records older than the organization’s Route history (30 days on Free, 1 year on Pro and Team, 3 years on Business) are accepted and dropped. Each record is checked on its own: skipped counts the ones refused.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
The organization ID (org- and 12 hex digits)
History lines from cedr route sync, each a pick, a verdict or a council result (cedr’s Route contract). A record of any other type is skipped.
object
With an offset; more than five minutes ahead of the server is refused.
The rules hash of the routes the pick used.
<harness>/<model>.
Set when the pick was made for a preview model version’s trial cell.
Ties the picks of one cascade (draft
The draft pick this pick judges. Not together with escalates.
The draft pick this pick escalates. Not together with judges.
object
A pick you synced.
One line.
One cedr council merge result. Counts only; never files, lines or claims.
object
The council route
The plan’s run
Merged groups per severity.
object
Findings each reviewer reported, zero included, keyed by <harness>/<model> (at most 64 keys).
object
Example
{ "org": "northwind", "records": [ { "type": "pick", "id": "p-1a2b3c4d5e6f", "at": "2026-10-29T07:42:00Z", "route": "review.code", "rules": "8ff065e", "target": "codex/gpt-6.1-sol", "effort": "high", "reason": "primary", "state": "ready", "size": "medium" }, { "type": "verdict", "id": "p-1a2b3c4d5e6f", "at": "2026-10-29T08:10:00Z", "verdict": "accepted" }, { "type": "council", "id": "c-1a2b3c4d5e6f", "at": "2026-10-29T08:20:00Z", "route": "review.council", "run": "r-1a2b3c4d5e6f", "round": 1, "rounds": 1, "gate": "block", "next": "revise", "quorum": 2, "block": "P1", "reviewers": [ "codex/gpt-6.1-sol", "claude/claude-opus-5-5" ], "groups": { "P0": 0, "P1": 1, "P2": 0, "P3": 2 }, "findings": { "codex/gpt-6.1-sol": 2, "claude/claude-opus-5-5": 1 } } ]}Responses
Section titled “Responses”Every record is accounted for.
object
Records stored
Records refused: a verdict on a pick this organization does not have, a malformed record, an ID another member already used, a record dated ahead of the server, or a record type the app does not know.
Example
{ "accepted": 2, "skipped": 0}The request is malformed (bad_request); the message says what to send.
object
A stable code to branch on.
A readable explanation. Its wording may change.
Example
{ "error": "bad_request", "message": "Name the organization: ?org=<organization ID>."}The key is missing (missing_api_key) or invalid, expired or revoked (invalid_api_key). The WWW-Authenticate header names the Bearer scheme.
object
A stable code to branch on.
A readable explanation. Its wording may change.
Example
{ "error": "invalid_api_key", "message": "The key is invalid, expired or revoked."}Headers
Section titled “Headers”Example
Bearer realm="cedr.dev"The key’s owner is not a member of that organization (not_a_member).
object
A stable code to branch on.
A readable explanation. Its wording may change.
Example
{ "error": "not_a_member", "message": "You are not a member of an organization named northwind."}The body is over 1 MiB (too_large); send at most 500 records a request.
object
A stable code to branch on.
A readable explanation. Its wording may change.
Example
{ "error": "missing_api_key"}The key sent more requests in a minute than its owner’s plan allows (rate_limited): 30 on Free, 120 on Pro, 300 on Team and 600 on Business.
object
A stable code to branch on.
A readable explanation. Its wording may change.
Example
{ "error": "rate_limited", "message": "This key is over its plan's requests-a-minute limit."}Headers
Section titled “Headers”Seconds to wait before retrying.
Example
60Something failed on our side (internal_error). Retry with backoff.
object
A stable code to branch on.
A readable explanation. Its wording may change.
Example
{ "error": "internal_error", "message": "Something went wrong on our side. Try again."}