Skip to content

feat(core): send Idempotency-Key, the API's one idempotency header [SAP-4544] - #1272

Merged
xoxo-david merged 2 commits into
mainfrom
davidzhang/idempotency-key
Oct 30, 2026
Merged

xoxo-david merged 2 commits into
mainfrom
davidzhang/idempotency-key

Conversation

@xoxo-david

@xoxo-david xoxo-david commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Primary change type

  • Bug fix
  • Documentation
  • Feature
  • Tests
  • Dependency update
  • Maintenance or refactor

Problem and motivation

The Sapiom API is settling on one idempotency header, Idempotency-Key. Cancel, UCP checkout, executions and budgets already read it, and transaction create and the gateway's payment guard are being switched in the PRs above. The SDK still auto-generates X-Idempotency-Key on every POST/PUT/PATCH, and browser automation sends its key under both names, so integrators copying the SDK learn two headers.

Summary and scope

@sapiom/core's HttpClient now auto-generates Idempotency-Key. A key the caller passes under either spelling is still the request's key, and the client never adds a second, different one. @sapiom/tools browser automation sends its key once, as Idempotency-Key. The API accepts X-Idempotency-Key with the same meaning, so code that sets it keeps working.

Out of scope: @sapiom/tools executions already send Idempotency-Key. Internal service-to-service hops (gateway → backend) live in the Sapiom repo.

Related work

Related issue or discussion:
SAP-4544. It depends on sapiom/Sapiom#6250 (SAP-4512) and sapiom/Sapiom#6262 (SAP-4543).

Validation

pnpm --filter "@sapiom/tools..." build — passed
pnpm --filter @sapiom/core test — 143 passed
pnpm --filter @sapiom/tools test -- browser-automation — 84 passed
pnpm --filter @sapiom/core --filter @sapiom/tools lint — 0 errors (3 warnings, same as main)
pnpm --filter @sapiom/core --filter @sapiom/tools typecheck — passed

Tests and documentation

The SapiomClient tests now assert that Idempotency-Key is generated, kept across retries, and sent without the older spelling. A new test checks that a caller's X-Idempotency-Key is kept as the key, with no second key added. The browser automation spec asserts that only one header is sent. The browser automation README now names one header.

Compatibility and release impact

  • Breaking or externally visible changes: the auto-generated header is renamed from X-Idempotency-Key to Idempotency-Key. That's safe only once the API deploys listed above are live. Code that reads the header SDK requests are sent with (for example, a proxy) sees the new name.
  • Changeset: Added (@sapiom/core minor, @sapiom/tools patch).

Security

  • I have not included secrets, credentials, private data, or unsanitized logs.
  • This pull request does not publicly disclose a suspected vulnerability. I
    will follow the
    Security Policy for
    private reporting.

AI assistance

  • I did not use AI assistance for this change.
  • I used AI assistance and have described it below.

Claude Code (Claude Opus 5.5) traced every route the SDK's key reaches (the backend create and the vault via the gateway payment guard) to set the deploy order. It wrote the change, tests and changeset, and ran the build, tests, lint and typecheck listed above.

Checklist

  • I read CONTRIBUTING.md, and this contribution follows the direct-PR or issue-first policy.
  • This pull request addresses one focused problem and contains no unrelated cleanup.
  • I added or updated tests, or explained above why tests are not applicable.
  • I ran the relevant build, typecheck, lint, and test commands, or explained
    any N/A checks above.
  • I updated documentation for user-facing changes, or marked it N/A above.
  • I added a Changeset for a published-package change, or explained why it is not applicable.
  • I can explain and maintain every submitted change, including any AI-assisted work.

🤖 Generated with Claude Code

HttpClient auto-generated X-Idempotency-Key and browser automation sent its
key under both names. Both now send Idempotency-Key once. A caller's key under
either spelling is still the request's key, and HttpClient never adds a second
one; the API accepts X-Idempotency-Key with the same meaning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 46 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 67add147-3ee7-4a23-b59f-3e40a4a5f2e5
Commits

Reviewing files that changed from the base of the PR and between efa75d5 and 3214703.

Files selected for processing: 6
  • .changeset/idempotency-key-one-header.md
  • packages/core/src/client/HttpClient.ts
  • packages/core/src/client/SapiomClient.test.ts
  • packages/tools/src/browser-automation/README.md
  • packages/tools/src/browser-automation/managed.spec.ts
  • packages/tools/src/browser-automation/managed.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

gwitwer
gwitwer previously approved these changes Oct 29, 2026

@gwitwer gwitwer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved, with one condition before it leaves draft. The backend side is deployed: #6250 and #6262 are both in the 18:01Z backend deploy. #6262 also changes the x402 payment guard, which Render deploys. Please confirm on Render that unified (vault) is on a commit at or after 811dcfbeda before taking this out of draft.

@xoxo-david
xoxo-david marked this pull request as ready for review October 29, 2026 22:18
devin-ai-integration[bot]

This comment was marked as resolved.

…s own

The generated key is now `Idempotency-Key`, so a client-default
`X-Idempotency-Key` no longer gets overwritten in the header merge: both went
out with different values, and the API refuses that with a 400. When a request
carries a key under either spelling, default keys under both spellings are
dropped, so the request's key wins as before and only one is sent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@xoxo-david
xoxo-david requested a review from gwitwer October 29, 2026 22:45
@xoxo-david
xoxo-david merged commit 8df73a6 into main Oct 30, 2026
13 checks passed
@xoxo-david
xoxo-david deleted the davidzhang/idempotency-key branch October 30, 2026 04:21
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.

2 participants