Skip to content

fix(cms): align points API error format and OpenAPI spec#77

Merged
kasparkallas merged 3 commits into
mainfrom
kasparkallas/fix/points-api-error-format-openapi
Jul 10, 2026
Merged

fix(cms): align points API error format and OpenAPI spec#77
kasparkallas merged 3 commits into
mainfrom
kasparkallas/fix/points-api-error-format-openapi

Conversation

@kasparkallas

Copy link
Copy Markdown
Collaborator

Fixes the community-reported bug where GET /points/events still returned { error } instead of the documented { message }, and aligns the points OpenAPI spec with actual runtime behavior.

The three timestamp-validation 400s on /points/events were missed in the 2026-01-26 migration from { error } to { message } — the only remaining deviations in the points API. They now return message as the primary field, with a deprecated error duplicate kept temporarily so existing consumers don't break; it can be dropped in a later cleanup.

A follow-up audit of the whole points API surface (route handlers vs. schemas.ts/registry.ts) found several spec/implementation mismatches, fixed here as documentation-only changes:

  • POST /points/push documented only the single-event body shape, while the runtime accepts three formats; the request body now uses the (previously defined but unwired) PushRequestBodySchema union, so generated clients accept batch payloads
  • Examples and docs now prefer campaignId over the deprecated campaign field
  • Stale response examples gained the required cappedPoints/uncappedPoints fields
  • ApiError.invalid broadened to cover invalid campaign IDs (not just addresses); the missing field on signed-balance-batch 404s is now documented
  • lastEventAt descriptions corrected to reflect processing-time semantics (informational events excluded)
  • Smaller alignments: address-regex for events/push account, lenient timestamp parsing documented, machine-readable pagination defaults, lowercase-hex API key format, server-side-only note on the push endpoint

Deliberately not changed (to avoid behavior changes): CORS still blocks X-API-Key cross-origin (guardrail against embedding server keys in browsers), malformed JSON bodies still 500, and lenient integer/timestamp parsing is kept and documented rather than tightened.

Verified by fetching the live /points/openapi.json from a dev server and programmatically asserting all 20 expected spec changes, plus exercising the three fixed error responses end-to-end (400 + both keys).

🤖 Generated with Claude Code

The three timestamp-validation errors on GET /points/events still returned
{ error } after the 2026-01-26 migration to { message } (reported by a
community member). They now return message as the primary field, with a
deprecated error duplicate kept temporarily for backward compatibility.

Also align the OpenAPI spec with actual runtime behavior:

- Document all three accepted POST /points/push request formats via
  PushRequestBodySchema instead of only the single-event shape, and
  register the batch schemas as components
- Prefer campaignId over the deprecated campaign field in all examples
- Add missing cappedPoints/uncappedPoints to stale response examples
- Broaden ApiError.invalid to unknown[] and document the missing field
  returned by signed-balance-batch 404s
- Correct lastEventAt descriptions (processing time, not eventTime)
- Use the address-regex schema for events/push account fields, document
  lenient timestamp parsing, machine-readable pagination defaults, and
  lowercase-hex API key format
- Note that the push endpoint is for server-side use only

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
superfluid-cms Ready Ready Preview, Comment Jul 9, 2026 7:08pm
superfluid-pro-website Ready Ready Preview, Comment Jul 9, 2026 7:08pm
superfluid-sdk-docs Ready Ready Preview, Comment Jul 9, 2026 7:08pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
superfluid-data Skipped Skipped Jul 9, 2026 7:08pm

Request Review

Add a Negative Points section to the API overview covering zero-clamped
balances, the risk that users skip re-claiming a reduced balance on-chain,
and the permissionless claim-on-behalf mitigation. Reference it from the
push and signed-balance endpoint descriptions and the points field docs.

Also do an editing pass on the embedded documentation: move API Basics
above the TypeScript client guide, rename Rate Limits to Request Limits,
show signature hashes with their exact encodePacked type encoding, make
JSON examples valid JSON, and refresh stale example timestamps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The per-event batch format in the points push OpenAPI spec typed its
events as PushEvent, which advertises campaignId/campaign per event.
The runtime validator only accepts eventName, account, points and
uniqueId per event; campaign is read at the root level only, so the
documented per-event campaign fields were silently ignored and would
surface as dead fields in generated clients.

Add a BatchPerEventItem doc schema matching the runtime shape and use
it in BatchWithPerEventRequest. No runtime behavior change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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