Resolve API
Execution-verified bug fixes: submit a repo and an issue, accept the quote, get a public attestation.
Base URL https://resolve.codai.ro; the same codai_ key you use on the gateway. Private beta: public github.com repos, Python/pytest verification. No fix, no fee — a charge is written only after the attestation exists, and every money field is USD micros. Attestations are public by URL (the uuid is the capability). The error body here is { "error": "<string>" }, not the gateway envelope.
bearerAuthAuthorizationBearer <codai_…>An existing codai API key. Jobs are scoped to the key's user; all keys of one user share the same limits and free tier.
application/json- body
Body of POST /v1/resolve/jobs. Provide issue_url or issue_text (at least one).
repo_url*stringPublic GitHub repository, https://github.com/owner/repo (optional .git or trailing slash). Anything else is rejected with 400.
uriissue_url?stringPublic GitHub issue URL https://github.com/owner/repo/issues/123. Fetched without a token; ignored when issue_text is present.
uriissue_text?stringInline issue description. Takes precedence over issue_url. Only the first 20 000 characters reach triage.
10 <= length <= 50000test_command?stringOptional FAIL_TO_PASS command (must fail before the fix and pass after). When omitted the agent writes a repro test first and includes it in the attestation.
length <= 2000callback_url?stringOptional webhook target. Must be https, carry no credentials and point at a public
host (no localhost, private, link-local or metadata addresses; every DNS answer is
re-checked at delivery). Events are signed with the per-job callback_secret
returned in the intake response. Redirects are not followed.
urilength <= 2000Job created but declined by triage.
application/json- response
200 body — triage declined the issue. The job is persisted with status: declined and is never billed.
id*stringuuidstatus*stringdecline_reason*stringcallback_secret?stringPresent only when the intake carried callback_url (a job.declined event is sent
too). HMAC-SHA256 key for webhook signatures. Returned once — store it now.
curl -X POST 'https://resolve.codai.ro/v1/resolve/jobs' \ -H 'Content-Type: application/json' \ -d '{ "repo_url": "https://github.com/psf/requests"}'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "status": "declined", "decline_reason": "feature request, no testable behavior", "callback_secret": "whsec_3q2-7wQ1d0X9mZk4Vb8yTnR5sLpA6cEe"}bearerAuthAuthorizationBearer <codai_…>An existing codai API key. Jobs are scoped to the key's user; all keys of one user share the same limits and free tier.
id*stringJob UUID returned by POST /v1/resolve/jobs.
uuidJob found.
application/json- response
Full job view returned by GET /v1/resolve/jobs/{id}. Nullable fields are null until the corresponding stage has run.
id*stringuuidstatus*Job statusLifecycle: triage → quoted → accepted → running → resolved | failed, plus declined
(triage refused) and error (infrastructure failure — retryable, never billed).
"triage""quoted""declined""accepted""running""resolved""failed""error"repo_url*stringNormalised repository URL (trailing slash removed).
uritier*|Quote tier; null until triage completes.
quote_micro_usd*|Quoted price in USD micros; null until quoted, 0 on the free tier.
paid_with?Payment methodPresent once the job was accepted (and recorded how it was paid).
"intro""credit""wallet""free"triage_reason*string|nulldecline_reason*|Set only when status is declined.
fail_reason*|Set when status is failed or error (e.g. dispatch failed: …).
cost_micro_usd*integerUpstream inference spend attributed to this job, USD micros. Informational — you are billed the quote, not the cost.
attestation_id*|Present once the job is resolved.
uuidattestation_url*|Relative path /v1/resolve/attestations/{attestation_id}; null until resolved.
created_at*stringdate-timecompleted_at*|date-timeissue_url?|The GitHub issue URL given at intake; null when the issue was sent as text.
uriissue_title?|First line of the issue text (at most 120 characters); null when unknown.
curl -X GET 'https://resolve.codai.ro/v1/resolve/jobs/497f6eca-6276-4993-bfeb-53cbbbba6f08'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "status": "triage", "repo_url": "http://example.com", "tier": "free", "quote_micro_usd": 0, "paid_with": "intro", "triage_reason": "string", "decline_reason": "string", "fail_reason": "string", "cost_micro_usd": 0, "attestation_id": "e21e05b4-d2f4-4bc0-ba2d-fc19366a584b", "attestation_url": "/v1/resolve/attestations/1f2c1a3e-8d4b-4f8e-9a1b-0c2d3e4f5a6b", "created_at": "2019-08-24T14:15:22Z", "completed_at": "2019-08-24T14:15:22Z", "issue_url": "http://example.com", "issue_title": "string"}bearerAuthAuthorizationBearer <codai_…>An existing codai API key. Jobs are scoped to the key's user; all keys of one user share the same limits and free tier.
id*stringJob UUID returned by POST /v1/resolve/jobs.
uuidJob accepted and dispatched.
application/json- response
id*stringuuidstatus*stringpaid_with*Payment methodHow an accepted job is paid: free (free tier), intro (first paid job, €1 hold),
credit (one t7 fix credit, no wallet hold) or wallet (hold of the list price).
Precedence: free > intro > credit > wallet.
"intro""credit""wallet""free"held_micro_eur*integerAmount held on the wallet in EUR micros — 1000000 for the intro, the quote for wallet, 0 for credit.
0 <= valuecurl -X POST 'https://resolve.codai.ro/v1/resolve/jobs/497f6eca-6276-4993-bfeb-53cbbbba6f08/accept'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "status": "accepted", "paid_with": "intro", "held_micro_eur": 1000000}id*stringAttestation UUID (from attestation_id on the job).
uuidAttestation found.
application/json- response
Public execution proof. Everything needed to reproduce the verification locally.
id*stringuuidkind*stringrepo_url*stringuribase_commit*stringCommit SHA the patch applies to.
patch*stringUnified diff against base_commit.
repro_test*|null when the customer supplied test_command.
test_command*stringFAIL_TO_PASS command that was executed.
regression_command*|PASS_TO_PASS (repo suite) command, when one was run.
test_output_before*stringTail of the test output BEFORE the patch (must fail).
test_output_after*stringTail of the test output AFTER the patch (must pass).
regression_output*string|nullrunner_image_digest*stringContainer image digest of the verification runner (unknown when not recorded).
started_at*stringdate-timeverified_at*stringdate-timesignature*|DSSE envelope signing the canonical statement of this attestation (sha256 of the patch,
repro test, test outputs; commands, commit, runner digest, timestamps). null for
attestations created before signing was enabled (2026-09-27). Verify against
GET /v1/resolve/keys.
curl -X GET 'https://resolve.codai.ro/v1/resolve/attestations/497f6eca-6276-4993-bfeb-53cbbbba6f08'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "kind": "codai.resolve.attestation.v0", "repo_url": "http://example.com", "base_commit": "3f1e2d4c5b6a798877665544332211aabbccddee", "patch": "string", "repro_test": { "path": "tests/test_repro_issue_6000.py", "content": "string" }, "test_command": "string", "regression_command": "string", "test_output_before": "string", "test_output_after": "string", "regression_output": "string", "runner_image_digest": "string", "started_at": "2019-08-24T14:15:22Z", "verified_at": "2019-08-24T14:15:22Z", "signature": { "payloadType": "application/vnd.codai.resolve.attestation+json;v=1", "payload": "string", "signatures": [ { "keyid": "string", "sig": "string" } ] }}Service is up.
application/json- response
ok*booleanservice*stringcurl -X GET 'https://resolve.codai.ro/health'{ "ok": true, "service": "codai-resolve"}Last updated: