跳转到内容

ak.schema.push_operations.v1

← Schemas

Arkret Push Gateway Operation DTOs
ak.schema.push_operations.v1 · file: schemas/push-operations.schema.json

Closed request and response DTOs for Station device registration, trusted public-Gateway registration handoff, and push notification delivery.

* $ · anyOf[7]
Closed request and response DTOs for Station device registration, trusted public-Gateway registration handoff, and push notification delivery.
anyOf · anyOf[0] · object · $ref #/$defs/push_register_device_request_body
Account Station self-service registration. The authenticated exact AccountId supplies registration scope and its station_id must equal the receiving Station service identity. A push_gateway role cannot accept this operation on its own authority.
* device_id · string · $ref #/$defs/device_id
pattern: ^ak:device:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
* push_gateway_url · allOf[2]
allOf · allOf[0] · string (uri) · format=uri · $ref #/$defs/uri
allOf · allOf[1] · ?
pattern: ^https://
* push_key · string · $ref #/$defs/push_key
platform · string · $ref #/$defs/non_empty_string
app_id · allOf[2]
allOf · allOf[0] · string · $ref #/$defs/non_empty_string
allOf · allOf[1] · ? · $ref string-profiles.schema.json#/$defs/non_typed_identifier_floor
Lexical floor of every identifier value category that does NOT own the ak: namespace (opaque_correlation, document_local_symbol, external_system_identifier, registry_catalog_symbol, unregistered_object_identifier); see common-fields.md 2.1. The negative lookahead IS the floor: it mechanically proves the value cannot be an ak: typed id, which maxLength alone can never prove, while admitting every other value the field already accepted. It deliberately constrains nothing else - the per-field convergence direction (a registered typed kind, or a tighter opaque profile) is decided per object family, so a pattern-only floor composes with whatever profile the field already carries instead of pre-empting it.
pattern: ^(?!ak:)
display_name · string (arkret-single-line-display-text) · format=arkret-single-line-display-text · $ref string-profiles.schema.json#/$defs/display_text_256
NFC multilingual single-line display text; mixed scripts, emoji, and symbols are allowed.
pattern: ^[^\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF]*[^\s\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF][^\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF]*$
visible_notification_opt_in · boolean
Receiver device authorization state for ak.profile.push_gateway.visible_notification.v1. Missing or false means this device MUST receive only blind_wakeup output even if the caller service is plaintext-visible; visible metadata requires an explicit per-device opt-in.
example: false
anyOf · anyOf[1] · object · $ref #/$defs/push_register_device_outcome
* push_target_id · string · $ref ./common-ids.schema.json#/$defs/push_target_id
Canonical typed pairwise push pseudonym. The suffix is the unpadded Base64URL encoding of the complete 32-octet HMAC-SHA256 output for one (recipient_id, principal_id, device_id, push_route, salt_epoch_id) tuple. Receivers MUST decode exactly 32 octets and require canonical re-encoding; it is never a DID, object id, raw provider token, or stable cross-service correlation key.
pattern: ^ak:pseudonym:push:[A-Za-z0-9_-]{42}[048AEIMQUYcgkosw]$
* registration_id · string · $ref #/$defs/registration_id
Station-generated, high-entropy, pairwise registration identity scoped to one exact AccountId/device/push route and destination Gateway. It is not an Arkret typed ID, MUST NOT begin with ak:, MUST NOT encode account or provider material, and MUST never be reused after terminal revocation. A replacement allocates a new registration_id and names the exact predecessor through supersedes_registration_id.
pattern: ^(?!ak:)[A-Za-z0-9._~-]{22,128}$
expires_at · string (date-time) · format=date-time · $ref #/$defs/timestamp
Canonical Arkret-owned absolute instant. UTC Z form with exactly three millisecond digits. Whole seconds MUST use .000Z; offsets, missing/finer fractions, lowercase separators, leap seconds, and invalid Gregorian calendar dates are forbidden. Shape validation by this pattern is supplemented by semantic date validation.
pattern: ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}Z$
anyOf · anyOf[2] · object · $ref #/$defs/push_unregister_device_request_body
Account Station self-service unregistration under the same exact authenticated AccountId/device authority as registration; gateway notify authority is insufficient.
* device_id · string · $ref #/$defs/device_id
pattern: ^ak:device:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
push_key · string · $ref #/$defs/push_key
app_id · allOf[2]
allOf · allOf[0] · string · $ref #/$defs/non_empty_string
allOf · allOf[1] · ? · $ref string-profiles.schema.json#/$defs/non_typed_identifier_floor
Lexical floor of every identifier value category that does NOT own the ak: namespace (opaque_correlation, document_local_symbol, external_system_identifier, registry_catalog_symbol, unregistered_object_identifier); see common-fields.md 2.1. The negative lookahead IS the floor: it mechanically proves the value cannot be an ak: typed id, which maxLength alone can never prove, while admitting every other value the field already accepted. It deliberately constrains nothing else - the per-field convergence direction (a registered typed kind, or a tighter opaque profile) is decided per object family, so a pattern-only floor composes with whatever profile the field already carries instead of pre-empting it.
pattern: ^(?!ak:)
anyOf · anyOf[3] · oneOf[2] · $ref #/$defs/push_registration_handoff_request_body
Station-to-Gateway desired registration state. The HTTP Message Signature binds exact Source-Service-ID, Destination-Service-ID and Content-Digest. The Gateway keys state by authenticated source tenant plus registration_id; a byte-identical replay returns the original receipt, different content for the same key is duplicate_conflict, and revoked is terminal.
oneOf · oneOf[0] · object · $ref #/$defs/push_registration_handoff_active
Immutable active installation submitted by the authenticated source Station to one trusted public Gateway. Source and destination service identities are carried only by signed HTTP headers. The source Station is the only notify source authorized by this minimal handoff contract; delegation is not inferred from profile claims or body fields.
* registration_id · string · $ref #/$defs/registration_id
Station-generated, high-entropy, pairwise registration identity scoped to one exact AccountId/device/push route and destination Gateway. It is not an Arkret typed ID, MUST NOT begin with ak:, MUST NOT encode account or provider material, and MUST never be reused after terminal revocation. A replacement allocates a new registration_id and names the exact predecessor through supersedes_registration_id.
pattern: ^(?!ak:)[A-Za-z0-9._~-]{22,128}$
* push_target_id · string · $ref ./common-ids.schema.json#/$defs/push_target_id
Canonical typed pairwise push pseudonym. The suffix is the unpadded Base64URL encoding of the complete 32-octet HMAC-SHA256 output for one (recipient_id, principal_id, device_id, push_route, salt_epoch_id) tuple. Receivers MUST decode exactly 32 octets and require canonical re-encoding; it is never a DID, object id, raw provider token, or stable cross-service correlation key.
pattern: ^ak:pseudonym:push:[A-Za-z0-9_-]{42}[048AEIMQUYcgkosw]$
* device_id · string · $ref #/$defs/device_id
pattern: ^ak:device:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
* state · const "active"
enum: "active"
* push_key · string · $ref #/$defs/push_key
Provider route secret disclosed only to the destination Gateway's authenticated Source-Service-ID tenant partition. It MUST NOT enter notify, receipts, logs, metrics, traces, cross-tenant indexes, or provider payload fields other than the provider address required for delivery.
platform · string · $ref #/$defs/non_empty_string
app_id · allOf[2]
allOf · allOf[0] · string · $ref #/$defs/non_empty_string
allOf · allOf[1] · ? · $ref string-profiles.schema.json#/$defs/non_typed_identifier_floor
Lexical floor of every identifier value category that does NOT own the ak: namespace (opaque_correlation, document_local_symbol, external_system_identifier, registry_catalog_symbol, unregistered_object_identifier); see common-fields.md 2.1. The negative lookahead IS the floor: it mechanically proves the value cannot be an ak: typed id, which maxLength alone can never prove, while admitting every other value the field already accepted. It deliberately constrains nothing else - the per-field convergence direction (a registered typed kind, or a tighter opaque profile) is decided per object family, so a pattern-only floor composes with whatever profile the field already carries instead of pre-empting it.
pattern: ^(?!ak:)
* visible_notification_opt_in · boolean
Exact device opt-in derived by the source Station. False restricts the installation to blind wakeup even when the Gateway also advertises the visible-notification profile.
expires_at · string (date-time) · format=date-time · $ref #/$defs/timestamp
Canonical Arkret-owned absolute instant. UTC Z form with exactly three millisecond digits. Whole seconds MUST use .000Z; offsets, missing/finer fractions, lowercase separators, leap seconds, and invalid Gregorian calendar dates are forbidden. Shape validation by this pattern is supplemented by semantic date validation.
pattern: ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}Z$
supersedes_registration_id · string · $ref #/$defs/registration_id
Station-generated, high-entropy, pairwise registration identity scoped to one exact AccountId/device/push route and destination Gateway. It is not an Arkret typed ID, MUST NOT begin with ak:, MUST NOT encode account or provider material, and MUST never be reused after terminal revocation. A replacement allocates a new registration_id and names the exact predecessor through supersedes_registration_id.
pattern: ^(?!ak:)[A-Za-z0-9._~-]{22,128}$
oneOf · oneOf[1] · object · $ref #/$defs/push_registration_handoff_revoked
Terminal handoff tombstone. It carries no provider route, application metadata, opt-in, account identity, or replacement value. The Gateway retains the minimal (source Station, registration_id, request digest, outcome) high-water needed to reject a delayed active install after private material is erased.
* registration_id · string · $ref #/$defs/registration_id
Station-generated, high-entropy, pairwise registration identity scoped to one exact AccountId/device/push route and destination Gateway. It is not an Arkret typed ID, MUST NOT begin with ak:, MUST NOT encode account or provider material, and MUST never be reused after terminal revocation. A replacement allocates a new registration_id and names the exact predecessor through supersedes_registration_id.
pattern: ^(?!ak:)[A-Za-z0-9._~-]{22,128}$
* push_target_id · string · $ref ./common-ids.schema.json#/$defs/push_target_id
Canonical typed pairwise push pseudonym. The suffix is the unpadded Base64URL encoding of the complete 32-octet HMAC-SHA256 output for one (recipient_id, principal_id, device_id, push_route, salt_epoch_id) tuple. Receivers MUST decode exactly 32 octets and require canonical re-encoding; it is never a DID, object id, raw provider token, or stable cross-service correlation key.
pattern: ^ak:pseudonym:push:[A-Za-z0-9_-]{42}[048AEIMQUYcgkosw]$
* device_id · string · $ref #/$defs/device_id
pattern: ^ak:device:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
* state · const "revoked"
enum: "revoked"
anyOf · anyOf[4] · object · $ref #/$defs/push_registration_handoff_outcome
* receipt · object · $ref #/$defs/push_registration_installation_receipt
Gateway-signed durable confirmation that the exact active installation or terminal tombstone was committed in the authenticated source Station tenant before success. The receipt grants no Account authority and contains no provider token.
* registration_id · string · $ref #/$defs/registration_id
Station-generated, high-entropy, pairwise registration identity scoped to one exact AccountId/device/push route and destination Gateway. It is not an Arkret typed ID, MUST NOT begin with ak:, MUST NOT encode account or provider material, and MUST never be reused after terminal revocation. A replacement allocates a new registration_id and names the exact predecessor through supersedes_registration_id.
pattern: ^(?!ak:)[A-Za-z0-9._~-]{22,128}$
* push_target_id · string · $ref ./common-ids.schema.json#/$defs/push_target_id
Canonical typed pairwise push pseudonym. The suffix is the unpadded Base64URL encoding of the complete 32-octet HMAC-SHA256 output for one (recipient_id, principal_id, device_id, push_route, salt_epoch_id) tuple. Receivers MUST decode exactly 32 octets and require canonical re-encoding; it is never a DID, object id, raw provider token, or stable cross-service correlation key.
pattern: ^ak:pseudonym:push:[A-Za-z0-9_-]{42}[048AEIMQUYcgkosw]$
* device_id · string · $ref #/$defs/device_id
pattern: ^ak:device:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
* state · string (enum)
enum: "active" "revoked"
* request_digest · string
SHA-256 of RFC 8785 JCS of the complete handoff request body. It binds provider route bytes without repeating them in the receipt.
pattern: ^sha256:[0-9a-f]{64}$
* source_station_id · string · $ref ./common-ids.schema.json#/$defs/did_core_id
Canonical stable DID-derived identity core. The lowercase DID method name follows ak:did_core:, and the remaining method-adapter-defined core is opaque to generic consumers. The did:web v1 adapter uses the complete canonical method-specific-id, never a digest or truncated host. Principal-core and service-core equality is byte-for-byte equality of the complete did_core_id. Event actor and Realm membership equality instead use the complete closed ActorId, and account-scoped equality uses the complete AccountId; neither may be reduced to a principal core. A did_core_id is not a DID and cannot be resolved without a did or AuthenticatedServiceResolution.
pattern: ^ak:did_core:[a-z0-9]+:[^\s/?#]+$
* destination_gateway_id · string · $ref ./common-ids.schema.json#/$defs/did_core_id
Canonical stable DID-derived identity core. The lowercase DID method name follows ak:did_core:, and the remaining method-adapter-defined core is opaque to generic consumers. The did:web v1 adapter uses the complete canonical method-specific-id, never a digest or truncated host. Principal-core and service-core equality is byte-for-byte equality of the complete did_core_id. Event actor and Realm membership equality instead use the complete closed ActorId, and account-scoped equality uses the complete AccountId; neither may be reduced to a principal core. A did_core_id is not a DID and cannot be resolved without a did or AuthenticatedServiceResolution.
pattern: ^ak:did_core:[a-z0-9]+:[^\s/?#]+$
* stored_at · string (date-time) · format=date-time · $ref #/$defs/timestamp
Canonical Arkret-owned absolute instant. UTC Z form with exactly three millisecond digits. Whole seconds MUST use .000Z; offsets, missing/finer fractions, lowercase separators, leap seconds, and invalid Gregorian calendar dates are forbidden. Shape validation by this pattern is supplemented by semantic date validation.
pattern: ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}Z$
* proof · object · $ref ./event-envelope.schema.json#/$defs/proof
Generic detached-JWS proof shape reused by non-Event schemas (snapshot signature, snapshot witness attestations, identity receipts, handle claims, etc.). MUST NOT be used as the shape of Event Envelope `producer_proof` — Event proofs reference $defs/event_proof and bind canonical Event bytes via `event_digest`. Non-Event signed objects MUST define an object-family signing-context constant and include it in the canonical proof binding object with payload_digest; the context constant is not a wire field in this generic shape. drift detection: `payload_digest#event_proof` in forbidden-wire-fields.json is the hard-reject mirror of this rule. New non-Event signed objects MAY $ref this shape; new signed Event-shaped objects MUST instead $ref event_proof.
* kind · string (enum)
Generic detached JWS proof over a canonical non-Event payload binding object that includes an object-family context constant.
enum: "detached_jws"
* verification_method · string
DID URL of the signing key for this non-Event detached proof. Same pattern as $defs/event_proof.verification_method; semantics are decoupled from Event proof (see $defs/event_proof for the Event-only shape).
pattern: ^did:[a-z0-9]+:[^\s#?]+#[A-Za-z0-9._:-]+$
* payload_digest · $ref #/$defs/digest · $ref #/$defs/digest
Generic non-Event detached-proof hash. This $defs/proof shape is reused by non-Event schemas; Event.properties.producer_proof references $defs/event_proof and MUST use event_digest instead.
* created_at · string (date-time) · format=date-time · $ref #/$defs/timestamp
Canonical Arkret-owned absolute instant. UTC Z form with exactly three millisecond digits. Whole seconds MUST use .000Z; offsets, missing/finer fractions, lowercase separators, leap seconds, and invalid Gregorian calendar dates are forbidden. Shape validation by this pattern is supplemented by semantic date validation.
pattern: ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}Z$
domain · string
audience · oneOf[2]
oneOf · oneOf[0] · string
oneOf · oneOf[1] · array<string>
items · string
proof_purpose · string (enum)
Optional role discriminator for non-Event proofs. HandleClaim core, status and revocation carriers make issuer_attestation, holder_acceptance, status_attestation and revocation_authorization load-bearing. governance_authorization marks a resource-governance-key authorization (directory withdraw/takedown-appeal, discovery-directory.md 8.7.1). Generic proof consumers ignore it unless their object-family contract makes it load-bearing.
enum: "issuer_attestation" "holder_acceptance" "status_attestation" "revocation_authorization" "governance_authorization"
* jws · string
pattern: ^[A-Za-z0-9_-]+\.\.[A-Za-z0-9_-]+$
anyOf · anyOf[5] · object · $ref #/$defs/push_notify_request_body
Closed Arkret notify body. Product-private notification bodies, provider adapter payloads, APNs/FCM/WebPush data dictionaries, `content`, `content_*`, `provider_payload`, DND/snooze state, and push-rule plaintext are outside this wire surface and MUST be consumed before this body is built. Provider-facing payloads are reconstructed by the gateway from this closed shape and MUST strip route_tokens / reason_code / event_kind / audit_envelope before provider dispatch.
* notification · oneOf[2]
oneOf · oneOf[0] · object · $ref #/$defs/blind_notification
* push_target_id · string · $ref ./common-ids.schema.json#/$defs/push_target_id
Canonical typed pairwise push pseudonym. The suffix is the unpadded Base64URL encoding of the complete 32-octet HMAC-SHA256 output for one (recipient_id, principal_id, device_id, push_route, salt_epoch_id) tuple. Receivers MUST decode exactly 32 octets and require canonical re-encoding; it is never a DID, object id, raw provider token, or stable cross-service correlation key.
pattern: ^ak:pseudonym:push:[A-Za-z0-9_-]{42}[048AEIMQUYcgkosw]$
* wakeup_kind · string (enum)
enum: "message" "mention" "assignment" "schedule" "reaction" "call_invite" "reminder" "scheduled_send" "expiry_invalidation"
push_hint · string (enum)
Sanitized hint sentinel. When the value is "l10n_key" the actual localization key MUST be carried in push_hint_l10n_key (this enum value is a form selector, not a literal display token). See push-notifications.md §5.1 / §4.5.
enum: "new_message" "incoming_call" "mention_self" "l10n_key"
push_hint_l10n_key · string · $ref #/$defs/non_empty_string
Localization key value, only present (and required) when push_hint == "l10n_key". MUST be an l10n key token, never plaintext body or any identifying metadata.
evaluation_locus_unresolved · boolean
Set true when the client has been woken but server-side rule matching is not yet resolved (E2EE client-side rule fallback). Pure local-evaluation signal; carries no metadata. See push-notifications.md §4.5.
counts · object · $ref #/$defs/counts
badge · oneOf[2]
Coarse unread indicator. Under blind_wakeup it MUST NOT carry a plaintext absolute unread count (activity side channel); only a boolean presence flag or a policy-declared bucket string is allowed. See push-notifications.md §5.1.
oneOf · oneOf[0] · boolean
oneOf · oneOf[1] · string
pattern: ^(?:0|[1-9][0-9]*(?:-[1-9][0-9]*|\+)?)$
unread_increment · integer
missed_call · oneOf[2]
Coarse missed-call indicator. Under blind_wakeup it MUST NOT carry a plaintext absolute count; only a boolean presence flag or the policy-declared bucket string is allowed. See push-notifications.md §5.1.
oneOf · oneOf[0] · boolean
oneOf · oneOf[1] · string
pattern: ^(?:0|[1-9][0-9]*(?:-[1-9][0-9]*|\+)?)$
route_tokens · object · $ref #/$defs/route_tokens
Gateway-internal opaque routing fragment shared by blind and visible notifications. Every field here drives gateway-side routing / dedup / circuit-breaker state and MUST be stripped before the gateway calls any push provider; it MUST NOT be forwarded to a provider. Tokens are issued by the destination Principal Service and bound to that service DID, push gateway service DID, purpose, scope, and salt epoch.
realm_route_token · string · $ref #/$defs/push_route_token
Opaque service-generated routing token. It MUST NOT contain, encode, or be reversibly derived from a DID, DID URL, Realm id, Circle id, Strand id, Message id, Event id, handle, platform push token, or stable cross-context correlation key.
pattern: ^[A-Za-z0-9._~-]{22,512}$
scope_route_token · string · $ref #/$defs/push_route_token
Opaque service-generated routing token. It MUST NOT contain, encode, or be reversibly derived from a DID, DID URL, Realm id, Circle id, Strand id, Message id, Event id, handle, platform push token, or stable cross-context correlation key.
pattern: ^[A-Za-z0-9._~-]{22,512}$
* devices · array<$ref #/$defs/device_route>
Nonempty unique device_id set. Routes, platform, application and visible-notification opt-in are resolved exclusively from authenticated current device registrations.
items · object · $ref #/$defs/device_route
Per-notification device selector only. The gateway obtains provider token, application, platform and explicit visible-notification opt-in solely from authenticated durable registration, and derives timing from source service, selected route and declared profile.
* device_id · string · $ref #/$defs/device_id
pattern: ^ak:device:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
oneOf · oneOf[1] · object · $ref #/$defs/visible_notification
* push_target_id · string · $ref ./common-ids.schema.json#/$defs/push_target_id
Canonical typed pairwise push pseudonym. The suffix is the unpadded Base64URL encoding of the complete 32-octet HMAC-SHA256 output for one (recipient_id, principal_id, device_id, push_route, salt_epoch_id) tuple. Receivers MUST decode exactly 32 octets and require canonical re-encoding; it is never a DID, object id, raw provider token, or stable cross-service correlation key.
pattern: ^ak:pseudonym:push:[A-Za-z0-9_-]{42}[048AEIMQUYcgkosw]$
* wakeup_kind · string (enum)
enum: "message" "mention" "assignment" "schedule" "reaction" "call_invite" "reminder" "scheduled_send" "expiry_invalidation"
push_hint · string (enum)
Sanitized hint sentinel. When the value is "l10n_key" the actual localization key MUST be carried in push_hint_l10n_key (this enum value is a form selector, not a literal display token). See push-notifications.md §5.1 / §4.5.
enum: "new_message" "incoming_call" "mention_self" "l10n_key"
push_hint_l10n_key · string · $ref #/$defs/non_empty_string
Localization key value, only present (and required) when push_hint == "l10n_key".
evaluation_locus_unresolved · boolean
Set true when the client has been woken but server-side rule matching is not yet resolved. See push-notifications.md §4.5.
counts · object · $ref #/$defs/counts
badge · oneOf[2]
Coarse unread indicator. Under blind_wakeup it MUST NOT carry a plaintext absolute unread count (activity side channel); only a boolean presence flag or a policy-declared bucket string is allowed. See push-notifications.md §5.1.
oneOf · oneOf[0] · boolean
oneOf · oneOf[1] · string
pattern: ^(?:0|[1-9][0-9]*(?:-[1-9][0-9]*|\+)?)$
unread_increment · integer
missed_call · oneOf[2]
Coarse missed-call indicator. Under blind_wakeup it MUST NOT carry a plaintext absolute count; only a boolean presence flag or the policy-declared bucket string is allowed. See push-notifications.md §5.1.
oneOf · oneOf[0] · boolean
oneOf · oneOf[1] · string
pattern: ^(?:0|[1-9][0-9]*(?:-[1-9][0-9]*|\+)?)$
route_tokens · object · $ref #/$defs/route_tokens
Gateway-internal opaque routing fragment shared by blind and visible notifications. Every field here drives gateway-side routing / dedup / circuit-breaker state and MUST be stripped before the gateway calls any push provider; it MUST NOT be forwarded to a provider. Tokens are issued by the destination Principal Service and bound to that service DID, push gateway service DID, purpose, scope, and salt epoch.
realm_route_token · string · $ref #/$defs/push_route_token
Opaque service-generated routing token. It MUST NOT contain, encode, or be reversibly derived from a DID, DID URL, Realm id, Circle id, Strand id, Message id, Event id, handle, platform push token, or stable cross-context correlation key.
pattern: ^[A-Za-z0-9._~-]{22,512}$
scope_route_token · string · $ref #/$defs/push_route_token
Opaque service-generated routing token. It MUST NOT contain, encode, or be reversibly derived from a DID, DID URL, Realm id, Circle id, Strand id, Message id, Event id, handle, platform push token, or stable cross-context correlation key.
pattern: ^[A-Za-z0-9._~-]{22,512}$
* devices · array<$ref #/$defs/device_route>
Nonempty unique device_id set. Routes, platform, application and visible-notification opt-in are resolved exclusively from authenticated current device registrations.
items · object · $ref #/$defs/device_route
Per-notification device selector only. The gateway obtains provider token, application, platform and explicit visible-notification opt-in solely from authenticated durable registration, and derives timing from source service, selected route and declared profile.
* device_id · string · $ref #/$defs/device_id
pattern: ^ak:device:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
* event_id · string · $ref #/$defs/event_id
pattern: ^ak:event:[A-Za-z0-9_-]{44}$
* realm_id · string · $ref ./common-ids.schema.json#/$defs/realm_id
Retyped ak.realm.create Event token. It therefore carries the same fixed current-v1 0x01/SHA-256 content-address identity and is not selected by Realm state.
pattern: ^ak:realm:[A-Za-z0-9_-]{44}$
* sender_actor_id · oneOf[2] · $ref ./common-ids.schema.json#/$defs/actor_id
Complete protocol identity for an Event author or Realm member: account carries the exact AccountId for every Station-hosted principal; service identifies a service acting as itself. The discriminator is validated against accepted registration and admission evidence; it never authorizes itself. Account and service are distinct, and no comparison may fall back to a bare principal_id. Agent and integration classification, provisioning, controller binding and credential authorization are independently verified facts, not identity variants. Account actors at different Stations MUST NOT share or inherit authority merely because their principal_id, DID controller or signing key matches, including membership, capability, RealmCommit-signing and recovery authority.
oneOf · oneOf[0] · object
* kind · const "account"
enum: "account"
* account_id · $ref #/$defs/account_id · $ref #/$defs/account_id
oneOf · oneOf[1] · object
* kind · const "service"
enum: "service"
* service_id · $ref #/$defs/did_core_id · $ref #/$defs/did_core_id
strand_id · string · $ref #/$defs/strand_id
pattern: ^ak:strand:[A-Za-z0-9_-]{44}$
message_id · string · $ref #/$defs/message_id
pattern: ^ak:message:[A-Za-z0-9_-]{44}$
sender_actor_display_name · string (arkret-single-line-display-text) · format=arkret-single-line-display-text · $ref string-profiles.schema.json#/$defs/display_text_256
NFC multilingual single-line display text; mixed scripts, emoji, and symbols are allowed.
pattern: ^[^\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF]*[^\s\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF][^\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF]*$
strand_title · string (arkret-single-line-display-text) · format=arkret-single-line-display-text · $ref string-profiles.schema.json#/$defs/display_text_512
NFC multilingual single-line display text; mixed scripts, emoji, and symbols are allowed.
pattern: ^[^\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF]*[^\s\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF][^\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF]*$
realm_title · string (arkret-single-line-display-text) · format=arkret-single-line-display-text · $ref string-profiles.schema.json#/$defs/display_text_256
NFC multilingual single-line display text; mixed scripts, emoji, and symbols are allowed.
pattern: ^[^\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF]*[^\s\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF][^\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069\uFEFF]*$
user_is_target · boolean
priority · string · $ref #/$defs/non_empty_string
membership · string · $ref #/$defs/non_empty_string
event_kind · string · $ref #/$defs/non_empty_string
Originating Event kind (e.g. `ak.message`) used by the gateway to route Phase-P2 `ak.agent.*` lifecycle / actor-private kinds to a no-fanout aak. Coarse routing selector; carries no Realm / sender / event identifier.
reason_code · string · $ref #/$defs/non_empty_string
Caller-supplied wire-safe reason code. The well-known value `historical_only` marks a diagnostic replay that MUST NOT trigger a fresh push fanout (the gateway answers a 200 idempotency-style ack). Other values are honored only where the operation defines them.
audit_envelope · object · $ref #/$defs/audit_envelope
`ak.audit.accessed` envelope routing fragment carried alongside a notify request. When present, the request is an audit-pipeline event (e.g. an `e2ee_late_recovery` access notice), not a push notify: the gateway writes the audit event, acks 200, and skips the push pipeline.
* access_kind · string · $ref #/$defs/non_empty_string
ak.audit.accessed.access_kind. The gateway branches on `e2ee_late_recovery` to skip the push pipeline.
late_recovery_original_event_id · string · $ref #/$defs/event_id
REQUIRED (at the application layer) when access_kind == e2ee_late_recovery. References the original encrypted event for audit only; this marker does not prove historical membership or authorize plaintext disclosure.
pattern: ^ak:event:[A-Za-z0-9_-]{44}$
anyOf · anyOf[6] · object · $ref #/$defs/push_notify_outcome
Closed notify response. outcomes[] is conserved against notification.devices[]: every input device_id appears exactly once, no device_id appears twice, and no device_id appears that was not requested. A target-level failure is expanded into one same-reason rejected outcome per input device rather than collapsing into a second response shape, so the conservation invariant holds unconditionally. Counts, if a deployment surfaces them, are derived from outcomes[] and are never an independent truth source.
* push_target_id · string · $ref ./common-ids.schema.json#/$defs/push_target_id
Canonical typed pairwise push pseudonym. The suffix is the unpadded Base64URL encoding of the complete 32-octet HMAC-SHA256 output for one (recipient_id, principal_id, device_id, push_route, salt_epoch_id) tuple. Receivers MUST decode exactly 32 octets and require canonical re-encoding; it is never a DID, object id, raw provider token, or stable cross-service correlation key.
pattern: ^ak:pseudonym:push:[A-Za-z0-9_-]{42}[048AEIMQUYcgkosw]$
* outcomes · array<$ref #/$defs/push_notify_device_outcome>
One entry per unique device_id in notification.devices[]. device_id MUST be unique across the array.
items · object · $ref #/$defs/push_notify_device_outcome
Gateway acceptance result for exactly one input device route. Identity is the (push_target_id, device_id) pair already carried by the request; no third route identifier exists. Provider delivery state, provider message ids, raw push tokens and token hashes MUST NOT appear here.
allOf · allOf[0] · ?
allOf · allOf[1] · ?
* device_id · string · $ref #/$defs/device_id
pattern: ^ak:device:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
* gateway_status · string (enum)
Closed gateway acceptance result. accepted = this request durably took the device route over. duplicate = an earlier request already took it over, or the operation explicitly requires a no-fanout acknowledgement, and this request produced no new delivery. A no-fanout acknowledgement does not assert provider acceptance, queueing or new durable route ownership. rejected = the gateway did not take it over. accepted and duplicate both mean the caller MUST NOT resend this device; only rejected may be resent, and only when retry_after_ms is present. See push-notifications.md §5.2.
enum: "accepted" "duplicate" "rejected"
reason_code · string (enum)
Closed rejection reason, all registered in error-code-registry.json. The first four are target-level or policy rejections; push_token_unknown / push_token_invalid tell the caller to drop this device registration; the last two are the only caller-retryable reasons. REQUIRED when gateway_status=rejected and MUST be absent otherwise.
enum: "push_target_unknown" "push_payload_too_large" "unsupported_profile" "push_token_unknown" "push_token_invalid" "push_gateway_unreachable" "rate_limited"
retry_after_ms · integer
Caller-facing backoff. Present only when the gateway did not take the route over AND the reason is one the caller can retry; its presence is the sole wire signal that the caller — not the gateway — owns the next attempt. A durably accepted route is retried by the gateway and never carries this field.

Source