Skip to content

feat(sdk): send an Idempotency-Key with a project create - #9

Merged
Upd4ting merged 2 commits into
mainfrom
feat/project-create-idempotency-key
Nov 11, 2026
Merged

Upd4ting merged 2 commits into
mainfrom
feat/project-create-idempotency-key

Conversation

@Upd4ting

@Upd4ting Upd4ting commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

Why

The dms-antelope-cloud first-run setup (ANT-1906) has to retry a project create whose answer was lost and get its own project back, instead of guessing ownership from slug, region and repository. The cloud now accepts an Idempotency-Key on POST /api/cloud/projects (ANT-1993). This PR exposes it in the spec and the SDK. Task: ANT-2016.

What changes

  • sdk/openapi/projects.yaml (new) holds the /api/cloud/projects/ path item, moved out of cloud.openapi.yaml, which would otherwise pass its 20,000-byte test ceiling. listProjects is unchanged.
  • createProject declares an optional Idempotency-Key header: a string of 1 to 255 visible ASCII characters (0x21-0x7E).
  • New responses: 400 cloud.errors.projects.invalid_idempotency_key; 409 cloud.errors.projects.slug_taken and cloud.errors.projects.creation_in_progress; 422 cloud.errors.projects.idempotency_key_reused.
  • The operation describes the behaviour, matching AntelopeJS/cloud#637 (src/projects/create.ts at 4dab2553):
Request Answer
Same member, same key, same slug, region, repository and branch 200 with the project that key created: projectId, current slug, region, and the original environmentId and serviceId. No new project, no GitHub call, no room needed under the plan's ceiling.
Same member, same key, different request 422 idempotency_key_reused
Another key, no key, or another member's key, on a taken slug 409 slug_taken
Keyed request while another create holds the slug 409 creation_in_progress: retry with the same key
Malformed key 400 invalid_idempotency_key

A key belongs to its workspace and to the member who sent it.

  • CloudApi.createProject(body, { idempotencyKey }) sends the key as the header. Without one, no header is sent. The one-argument call keeps working.
  • The ajs cloud CLI sends no key. Its ensureProject never re-sends a create; it only retries slug_taken with another slug, so a key would never be reused.

Merge after AntelopeJS/cloud#637 (ANT-1993). The spec matches its route (src/routes/projects.ts) and creation flow (src/projects/create.ts) at 4dab2553: header name and pattern, every error code, the replay body, member scoping, and the digest fields.

Proof

sdk/test/api.test.ts: "a create sends its idempotency key as the Idempotency-Key header, and no header without one". It fails on a wrong header name, on a literal "undefined" header when no key is given, and on a body dropped when params is added.

Before (pnpm --dir sdk test on origin/main with the new test):

test/api.test.ts(133,7): error TS2554: Expected 1 arguments, but got 2.
 ELIFECYCLE  Test failed. See above for more details.

After:

  ✔ a create sends its idempotency key as the Idempotency-Key header, and no header without one (1.129025ms)
ℹ pass 36
ℹ fail 0

pnpm run checks: Checks: 11 passed, 0 failed. pnpm run check:generated: no diff.

sequenceDiagram
  participant C as Client (DMS setup)
  participant S as CloudApi.createProject
  participant A as POST /api/cloud/projects
  C->>S: body, { idempotencyKey: k }
  S->>A: Idempotency-Key: k
  A-->>S: 200 CreatedProject
  Note over C,A: answer lost, client retries
  C->>S: same body, { idempotencyKey: k }
  S->>A: Idempotency-Key: k
  A-->>S: 200 same project, no new one
  C->>S: other body, { idempotencyKey: k }
  S->>A: Idempotency-Key: k
  A-->>S: 422 idempotency_key_reused
  C->>S: same body, { idempotencyKey: k } while first create runs
  S->>A: Idempotency-Key: k
  A-->>S: 409 creation_in_progress, retry with k
Loading

@Upd4ting
Upd4ting merged commit 60c8a9a into main Nov 11, 2026
8 checks passed
@Upd4ting
Upd4ting deleted the feat/project-create-idempotency-key branch November 11, 2026 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant