---
title: "Modify Subscriptions"
method: POST
path: "/database/{version}/{container}/{environment}/{database}/subscriptions/modify"
tags: ["Subscriptions"]
---

# Modify Subscriptions

`POST /database/{version}/{container}/{environment}/{database}/subscriptions/modify`

Create, update, or delete subscriptions

## Path parameters

- `version` string, required — Protocol version
- `container` string, required — Container ID (begins with "iCloud.")
- `environment` 'development' | 'production', required — Container environment
- `database` 'public' | 'private' | 'shared', required — Database scope

## Request body

- object
  - `operations` SubscriptionOperation[]
    - `operationType` 'create' | 'update' | 'delete'
    - `subscription` Subscription — A CloudKit subscription — a persistent server-side trigger that produces push notifications when matching changes occur. Mirrors `CloudKit.Subscription` from the CloudKit JS reference.
      - `subscriptionID` string — Caller-supplied unique identifier for the subscription.
      - `subscriptionType` 'query' | 'zone'
      - `query` Query — A record query, shared by records/query and query subscriptions
        - `recordType` string — The record type to query
        - `filterBy` Filter[]
          - `comparator` 'EQUALS' | 'NOT_EQUALS' | 'LESS_THAN' | 'LESS_THAN_OR_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUALS' | 'NEAR' | 'CONTAINS_ALL_TOKENS' | 'IN' | 'NOT_IN' | 'CONTAINS_ANY_TOKENS' | 'LIST_CONTAINS' | 'NOT_LIST_CONTAINS' | 'BEGINS_WITH' | 'NOT_BEGINS_WITH' | 'LIST_MEMBER_BEGINS_WITH' | 'NOT_LIST_MEMBER_BEGINS_WITH'
          - `fieldName` string
          - `fieldValue` FieldValueRequest — A CloudKit field value for API requests. The type field is optional. It is required for the scalar types whose JSON representation is otherwise ambiguous (TIMESTAMP, BYTES, DOUBLE) and for the IN/NOT_IN list filters (the *_LIST types specify the list element type).
            - `value` union, required
              - …
            - `type` 'STRING' | 'INT64' | 'DOUBLE' | 'BYTES' | 'TIMESTAMP' | 'REFERENCE' | 'ASSET' | 'ASSETID' | 'LOCATION' | 'STRING_LIST' | 'INT64_LIST' | 'DOUBLE_LIST' | 'BYTES_LIST' | 'TIMESTAMP_LIST' | 'REFERENCE_LIST' | 'LOCATION_LIST' | 'ASSET_LIST' — Optional CloudKit field type. Sent for scalar values whose JSON form is ambiguous (e.g. "TIMESTAMP", "BYTES", "DOUBLE") so CloudKit does not infer the wrong type, and for IN/NOT_IN list filters (e.g. "INT64_LIST").
        - `sortBy` Sort[]
          - `fieldName` string
          - `ascending` boolean
      - `zoneID` ZoneID
        - `zoneName` string
        - `ownerName` string
      - `zoneWide` boolean — Zone subscriptions only. If `true`, the subscription watches *every zone* in the database (the wire representation of a native `CKDatabaseSubscription`); if `false`/absent, only the zone identified by `zoneID` is watched. Only valid against private and shared databases. Default `false`.
      - `firesOn` string[] — The record-change events that trigger a push (e.g. `[create, update]`). CloudKit treats the exact set as the subscription's uniqueness key — two subscriptions on the same `(recordType, firesOn)` tuple collide regardless of `subscriptionID`.
      - `firesOnce` boolean — If `true`, the subscription is destroyed after producing its first notification. Default `false`.
      - `notificationInfo` NotificationInfo — How CloudKit shapes the push notification produced by a subscription. Mirrors `CloudKit.NotificationInfo` from the CloudKit JS reference.
        - `alertBody` string — The text of the alert message.
        - `alertLocalizationKey` string — A key to a localized alert message.
        - `alertLocalizationArgs` string[] — Strings that appear as variables if `alertLocalizationKey` is a format specifier.
        - `alertActionLocalizationKey` string — A key to the localized title of the alert's action button.
        - `alertLaunchImage` string — The filename of the image to use as the launch image.
        - `soundName` string — The filename of the sound to play when the notification arrives.
        - `shouldBadge` boolean — Whether the app icon's badge should be incremented. Default `false`.
        - `shouldSendContentAvailable` boolean — Whether the notification should mark new content as available (silent background fetch). Default `false`.
        - `additionalFields` string[] — Names of record fields whose values should be included in the notification payload.
        - `category` string — The notification category (UN actionable category identifier).

## Response `200`

Subscriptions modified successfully

- SubscriptionsModifyResponse
  - `subscriptions` union[]
    - union
      - SubscriptionOperationFailure — Shared fields of a per-item failure entry returned inline in a 200 modify/lookup response. Composed into `RecordOperationFailure` and `SubscriptionOperationFailure` via `allOf`; each concrete failure type adds its own wire identifier (`recordName` / `subscriptionID`).
        - `serverErrorCode` 'ACCESS_DENIED' | 'ATOMIC_ERROR' | 'AUTHENTICATION_FAILED' | 'AUTHENTICATION_REQUIRED' | 'BAD_REQUEST' | 'CONFLICT' | 'EXISTS' | 'INTERNAL_ERROR' | 'NOT_FOUND' | 'QUOTA_EXCEEDED' | 'THROTTLED' | 'TRY_AGAIN_LATER' | 'VALIDATING_REFERENCE_ERROR' | 'ZONE_NOT_FOUND', required — The CloudKit server error code returned in a per-item failure entry (record or subscription) inline in a 200 modify/lookup response. Shared by `RecordOperationFailure` and `SubscriptionOperationFailure` via `OperationFailureCommon`. Distinct from `ErrorResponse`'s `serverErrorCode`, which carries a broader set of codes for top-level 4xx/5xx HTTP failures.
        - `reason` string — A string indicating the reason for the error.
        - `retryAfter` integer — Suggested seconds to wait before retrying. Absent if not retryable.
        - `uuid` string — A unique identifier for this error.
        - `redirectURL` string — Redirect URL for sign-in; present when serverErrorCode is AUTHENTICATION_REQUIRED.
        - `subscriptionID` string, required — The identifier of the subscription the operation failed on.
      - Subscription — A CloudKit subscription — a persistent server-side trigger that produces push notifications when matching changes occur. Mirrors `CloudKit.Subscription` from the CloudKit JS reference.
        - `subscriptionID` string — Caller-supplied unique identifier for the subscription.
        - `subscriptionType` 'query' | 'zone'
        - `query` Query — A record query, shared by records/query and query subscriptions
          - `recordType` string — The record type to query
          - `filterBy` Filter[]
            - `comparator` 'EQUALS' | 'NOT_EQUALS' | 'LESS_THAN' | 'LESS_THAN_OR_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUALS' | 'NEAR' | 'CONTAINS_ALL_TOKENS' | 'IN' | 'NOT_IN' | 'CONTAINS_ANY_TOKENS' | 'LIST_CONTAINS' | 'NOT_LIST_CONTAINS' | 'BEGINS_WITH' | 'NOT_BEGINS_WITH' | 'LIST_MEMBER_BEGINS_WITH' | 'NOT_LIST_MEMBER_BEGINS_WITH'
            - `fieldName` string
            - `fieldValue` FieldValueRequest — A CloudKit field value for API requests. The type field is optional. It is required for the scalar types whose JSON representation is otherwise ambiguous (TIMESTAMP, BYTES, DOUBLE) and for the IN/NOT_IN list filters (the *_LIST types specify the list element type).
              - …
          - `sortBy` Sort[]
            - `fieldName` string
            - `ascending` boolean
        - `zoneID` ZoneID
          - `zoneName` string
          - `ownerName` string
        - `zoneWide` boolean — Zone subscriptions only. If `true`, the subscription watches *every zone* in the database (the wire representation of a native `CKDatabaseSubscription`); if `false`/absent, only the zone identified by `zoneID` is watched. Only valid against private and shared databases. Default `false`.
        - `firesOn` string[] — The record-change events that trigger a push (e.g. `[create, update]`). CloudKit treats the exact set as the subscription's uniqueness key — two subscriptions on the same `(recordType, firesOn)` tuple collide regardless of `subscriptionID`.
        - `firesOnce` boolean — If `true`, the subscription is destroyed after producing its first notification. Default `false`.
        - `notificationInfo` NotificationInfo — How CloudKit shapes the push notification produced by a subscription. Mirrors `CloudKit.NotificationInfo` from the CloudKit JS reference.
          - `alertBody` string — The text of the alert message.
          - `alertLocalizationKey` string — A key to a localized alert message.
          - `alertLocalizationArgs` string[] — Strings that appear as variables if `alertLocalizationKey` is a format specifier.
          - `alertActionLocalizationKey` string — A key to the localized title of the alert's action button.
          - `alertLaunchImage` string — The filename of the image to use as the launch image.
          - `soundName` string — The filename of the sound to play when the notification arrives.
          - `shouldBadge` boolean — Whether the app icon's badge should be incremented. Default `false`.
          - `shouldSendContentAvailable` boolean — Whether the notification should mark new content as available (silent background fetch). Default `false`.
          - `additionalFields` string[] — Names of record fields whose values should be included in the notification payload.
          - `category` string — The notification category (UN actionable category identifier).

## Other responses

- `400` — Error response shared by all endpoints. The body schema is the same for every 4xx/5xx status code; the HTTP status code itself disambiguates which CloudKit failure occurred. See Apple's CloudKit Web Services Error Codes documentation for the full code → status mapping: - 400 BadRequest (BAD_REQUEST, ATOMIC_ERROR) - 401 Unauthorized (AUTHENTICATION_FAILED) - 403 Forbidden (ACCESS_DENIED) - 404 NotFound (NOT_FOUND, ZONE_NOT_FOUND) - 409 Conflict (CONFLICT, EXISTS) - 412 PreconditionFailed (VALIDATING_REFERENCE_ERROR) - 413 RequestEntityTooLarge (QUOTA_EXCEEDED) - 421 UnprocessableEntity (AUTHENTICATION_REQUIRED) - 429 TooManyRequests (THROTTLED) - 500 InternalServerError (INTERNAL_ERROR) - 503 ServiceUnavailable (TRY_AGAIN_LATER)
- `401` — Error response shared by all endpoints. The body schema is the same for every 4xx/5xx status code; the HTTP status code itself disambiguates which CloudKit failure occurred. See Apple's CloudKit Web Services Error Codes documentation for the full code → status mapping: - 400 BadRequest (BAD_REQUEST, ATOMIC_ERROR) - 401 Unauthorized (AUTHENTICATION_FAILED) - 403 Forbidden (ACCESS_DENIED) - 404 NotFound (NOT_FOUND, ZONE_NOT_FOUND) - 409 Conflict (CONFLICT, EXISTS) - 412 PreconditionFailed (VALIDATING_REFERENCE_ERROR) - 413 RequestEntityTooLarge (QUOTA_EXCEEDED) - 421 UnprocessableEntity (AUTHENTICATION_REQUIRED) - 429 TooManyRequests (THROTTLED) - 500 InternalServerError (INTERNAL_ERROR) - 503 ServiceUnavailable (TRY_AGAIN_LATER)

## Changes

- **2026-05-31** `44029c7b63a3` — 2 breaking, 5 warning, 6 info
  - added `#/components/schemas/SubscriptionOperationFailure, #/components/schemas/Subscription` to the `subscriptions/items/` response property `oneOf` list for the response status `200`
  - the `subscriptions/items/` response's property type/format changed from `object`/`` to ``/`` for status `200`
  - removed the optional property `subscriptions/items/firesOn` from the response with the `200` status
  - removed the optional property `subscriptions/items/query` from the response with the `200` status
  - …9 more
- **2025-07-06** `a17a324ec78e` — 28 warning, 1 info
  - added the new `ACCESS_DENIED` enum value to the `serverErrorCode` response property for the response status `400`
  - added the new `ACCESS_DENIED` enum value to the `serverErrorCode` response property for the response status `401`
  - added the new `ATOMIC_ERROR` enum value to the `serverErrorCode` response property for the response status `400`
  - added the new `ATOMIC_ERROR` enum value to the `serverErrorCode` response property for the response status `401`
  - …25 more
- …earlier changes not shown

[Full history](https://skmtc.dev/brightdigit/apis/apple-cloudkit-web-services-api/changes/database/:version/:container/:environment/:database/subscriptions/modify/post.md)

---

[API](https://skmtc.dev/brightdigit/apis/apple-cloudkit-web-services-api.md) · [All operations](https://skmtc.dev/brightdigit/apis/apple-cloudkit-web-services-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/brightdigit/apple-cloudkit-web-services-api/revisions/db45a101c485/schema)
