Skip to content

Docs: Apple's CloudKit Web Services reference documents APNs token endpoints under the wrong path (/database/ vs /device/) #382

@leogdion

Description

@leogdion

Summary

Apple's CloudKit Web Services REST reference (the archived CreateTokens / RegisterTokens pages) documents the APNs token endpoints under the /database/ path, but the live service only routes those under /device/. Following the documentation as written results in a persistent 405 Method Not Allowed. This issue captures the discrepancy so it isn't re-discovered, and tracks how MistKit diverges from the published docs on purpose.

Discovered while implementing the subscriptions & APNs tokens epic (#379).

The discrepancy

Documented (Apple's archived REST reference):

POST /database/{version}/{container}/{environment}/{database}/tokens/create
POST /database/{version}/{container}/{environment}/{database}/tokens/register

What actually works (matches CloudKit JS):

POST /device/{version}/{container}/{environment}/tokens/create
POST /device/{version}/{container}/{environment}/tokens/register

Against the /database/... path the live service routes only OPTIONS and returns 405 Method Not Allowed (Allow: OPTIONS) for the POST. CloudKit JS calls setApiModuleName("device") for token requests, producing the /device/... path — which returns 200 with the expected { apnsEnvironment, apnsToken, webcourierURL } body.

Note the /device/ path is also container-scoped — there is no {database} segment, unlike most other endpoints.

Additional documentation bugs in the same reference

While cross-checking against the archived docs, two more discrepancies surfaced:

  1. tokens/register request body — Apple lists both apnsEnvironment and apnsToken as Required, but this is easy to miss; apnsEnvironment was initially omitted in our implementation.
  2. tokens/create response shape — Apple returns { apnsEnvironment, apnsToken, webcourierURL } (where webcourierURL is the long-poll URL for browser/Service-Worker callers). Earlier guesses at the shape (e.g. a webcAuthToken field) are not what the service returns.

How MistKit handles this

openapi.yaml already documents the working path and rationale:

  • /device/{version}/{container}/{environment}/tokens/create (openapi.yaml:804)
  • /device/{version}/{container}/{environment}/tokens/register (openapi.yaml:854)
  • TokenResponse schema with webcourierURL (openapi.yaml:1475)

Verified end-to-end: swift run mistdemo test-private phase 16 (createToken + registerToken) now returns 200 where it previously failed with 405.

Why file this

  • Apple's reference is archived and unlikely to be corrected, so the next person reading the docs will hit the same 405.
  • Our openapi.yaml intentionally diverges from the published docs; this issue is the canonical record of why, linked from the spec comments.
  • If Apple's behavior ever changes, this is where to track it.

References

  • Apple archived REST reference: CreateTokens / RegisterTokens (linked above)
  • CloudKit JS setApiModuleName("device") behavior
  • Epic Push Notifications & Subscriptions (epic) #379 (subscriptions & APNs tokens), commits ad3ea98, 9ca4333, e47a95d

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdocumentationImprovements or additions to documentation

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions