{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/api-evangelist/customer-io/main/json-schema/customer-io-activity-object-schema.json",
  "title": "activityObject",
  "x-generated": "2026-10-12",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/customer-io-journeys-api-openapi.yml#/components/schemas/activityObject",
  "x-scalar-ignore": true,
  "type": "object",
  "properties": {
    "customer_id": {
      "$ref": "#/$defs/customer_id"
    },
    "customer_identifiers": {
      "$ref": "#/$defs/customer_identifiers"
    },
    "data": {
      "oneOf": [
        {
          "title": "Message delivery",
          "type": "object",
          "properties": {
            "delivered": {
              "type": [
                "integer",
                "null"
              ],
              "format": "unix timestamp",
              "description": "The date-time when the message was delivered, if applicable."
            },
            "delivery_id": {
              "type": "string",
              "description": "The message ID."
            },
            "opened": {
              "type": [
                "boolean",
                "null"
              ],
              "description": "Indicates whether or not a customer opened a message, if the message was delivered."
            }
          }
        },
        {
          "title": "Attribute change",
          "description": "The name of the object is the attribute that changed.",
          "type": "object",
          "additionalProperties": {
            "x-additionalPropertyName": "Attribute Name",
            "$ref": "#/$defs/attributeChangeAction"
          }
        },
        {
          "title": "Consent record",
          "description": "The data for a `consent` activity. The activity's `name` is the action, `opted_in` or `opted_out`. Customer.io fills in the optional fields when the change that created the record has that information. See [Consent records](/messaging/channels/subscriptions/consent-records/#what-a-record-contains).",
          "type": "object",
          "properties": {
            "consent_state": {
              "type": "string",
              "description": "The state the change left the person in.",
              "enum": [
                "subscribed",
                "unsubscribed"
              ]
            },
            "collection_point": {
              "type": "string",
              "description": "Where the change came from, like your subscription center or an SMS reply. The `subscription_preference_migration` and `sender_optout_migration` values mark records that Customer.io imported from preferences and opt-outs that existed before your account recorded consent.",
              "enum": [
                "api",
                "carrier_report",
                "double_opt_in_confirmation",
                "form",
                "import",
                "in_app_prompt",
                "inbound_reply",
                "list_unsubscribe_header",
                "one_click_unsubscribe",
                "operator",
                "sender_optout_migration",
                "subscription_center",
                "subscription_preference_migration",
                "unsubscribe_link"
              ]
            },
            "channel": {
              "type": "string",
              "description": "The channel the consent applies to, like `email` or `sms`. Absent when the consent applies to all of your messages."
            },
            "topic_id": {
              "type": "integer",
              "description": "The subscription topic the consent applies to, if any."
            },
            "topic_name": {
              "type": "string",
              "description": "The topic's name when the change happened. Renaming the topic later doesn't change this value."
            },
            "sender_id": {
              "type": "integer",
              "description": "The sender identity the consent applies to, if any."
            },
            "from": {
              "type": "string",
              "description": "The sender's email address or phone number when the change happened."
            },
            "delivery_id": {
              "type": "string",
              "description": "The message the person responded to, like the email that contained the unsubscribe link."
            },
            "received_on": {
              "type": "string",
              "description": "The address or phone number the person's reply came from."
            },
            "profile_identifier": {
              "type": "string",
              "description": "The identifier your request used to find the person."
            },
            "profile_identifier_type": {
              "type": "string",
              "description": "The type of `profile_identifier`, like `email` or `id`."
            },
            "response": {
              "type": "string",
              "description": "What the person sent back, like the body of an SMS reply."
            },
            "source_event_id": {
              "type": "string",
              "description": "The ID of the activity that produced this record, like the inbound SMS that contained STOP."
            }
          }
        }
      ]
    },
    "delivery_id": {
      "type": "string",
      "description": "The message ID."
    },
    "delivery_type": {
      "type": "string",
      "description": "The recipient device, if applicable.",
      "enum": [
        "ios",
        "android",
        "email",
        "phone"
      ]
    },
    "id": {
      "description": "The identifier for the action.",
      "type": "string"
    },
    "timestamp": {
      "type": "integer",
      "format": "unix timestamp",
      "description": "The date and time when the action occurred."
    },
    "type": {
      "$ref": "#/$defs/activityTypes"
    },
    "name": {
      "type": "string",
      "description": "The name of the event, for `event` and `screen` activities. For `consent` activities, the consent action, which is `opted_in`, `opted_out`, or `voided`."
    },
    "url": {
      "type": "string",
      "description": "The page URL, for `page` activities."
    }
  },
  "$defs": {
    "activityTypes": {
      "x-scalar-ignore": true,
      "description": "The type of activity. Types with `_o:<object_type_id>` are for objects and types with `_r:<object_type_id>` are for relationships.",
      "type": "string",
      "enum": [
        "add_relationship",
        "anon_merge",
        "attempted_action",
        "attempted_email",
        "attempted_in_app",
        "attempted_push",
        "attempted_slack",
        "attempted_twilio",
        "attempted_webhook",
        "attempted_whatsapp",
        "attribute_change",
        "bounced_action",
        "bounced_email",
        "bounced_push",
        "bounced_twilio",
        "bounced_whatsapp",
        "clicked_action",
        "clicked_content",
        "clicked_email",
        "clicked_in_app",
        "clicked_push",
        "clicked_twilio",
        "clicked_webhook",
        "consent",
        "converted_action",
        "converted_content",
        "converted_email",
        "converted_in_app",
        "converted_slack",
        "converted_twilio",
        "converted_webhook",
        "converted_whatsapp",
        "deferred_action",
        "deferred_email",
        "deferred_in_app",
        "deferred_push",
        "deferred_slack",
        "deferred_twilio",
        "deferred_webhook",
        "deferred_whatsapp",
        "delete_relationship",
        "delivered_action",
        "delivered_email",
        "delivered_push",
        "delivered_twilio",
        "delivered_whatsapp",
        "device_change",
        "drafted_action",
        "drafted_email",
        "drafted_in_app",
        "drafted_push",
        "drafted_slack",
        "drafted_twilio",
        "drafted_webhook",
        "dropped_action",
        "dropped_email",
        "dropped_push",
        "dropped_twilio",
        "dropped_webhook",
        "dropped_whatasapp",
        "event",
        "failed_action",
        "failed_attribute_change",
        "failed_batch_update",
        "failed_email",
        "failed_event",
        "failed_in_app",
        "failed_object_journeys",
        "failed_push",
        "failed_query_collection",
        "failed_slack",
        "failed_twilio",
        "failed_webhook",
        "failed_whatsapp",
        "opened_action",
        "opened_email",
        "opened_in_app",
        "opened_push",
        "page",
        "profile_create",
        "profile_delete",
        "profile_merge",
        "relationship_attribute_change",
        "relationship_failed_attribute_change",
        "screen",
        "sent_action",
        "sent_email",
        "sent_in_app",
        "sent_push",
        "sent_slack",
        "sent_twilio",
        "sent_webhook",
        "sent_whatsapp",
        "skipped_update",
        "spammed_email",
        "suppressed_twilio",
        "suppressed_whatsapp",
        "topic_unsubscribed_email",
        "undeliverable_action",
        "undeliverable_email",
        "undeliverable_in_app",
        "undeliverable_push",
        "undeliverable_slack",
        "undeliverable_twilio",
        "undeliverable_webhook",
        "undeliverable_whatsapp",
        "unsubscribed_action",
        "unsubscribed_email",
        "viewed_content",
        "webhook_event",
        "_o:<object_type_id>:add_relationship",
        "_o:<object_type_id>:attribute_change",
        "_o:<object_type_id>:create",
        "_o:<object_type_id>:delete",
        "_o:<object_type_id>:delete_relationship",
        "_o:<object_type_id>:failed_attribute_change",
        "_r:<object_type_id>:attribute_change",
        "_r:<object_type_id>:failed_attribute_change"
      ]
    },
    "attributeChangeAction": {
      "x-scalar-ignore": true,
      "type": "object",
      "properties": {
        "from": {
          "type": "string",
          "description": "The old attribute value. If empty, the customer probably didn't bear the attribute before this action."
        },
        "to": {
          "type": "string",
          "description": "The new attribute value."
        }
      }
    },
    "cio_id": {
      "x-scalar-ignore": true,
      "type": "string",
      "description": "A unique identifier set by Customer.io, used to reference a person if you want to update their identifiers."
    },
    "customer_id": {
      "x-scalar-ignore": true,
      "type": [
        "string",
        "null"
      ],
      "description": "The ID of a customer profile, analogous to a \"person\" in the UI. If your workspace supports multiple identifiers (email and ID), this value can be null."
    },
    "customer_identifiers": {
      "x-scalar-ignore": true,
      "type": "object",
      "description": "Identifiers for the person in a response—`id`, `cio_id`, and `email`. Unset `id` or `email` values are `null`. We recommend this object over the less descriptive `customer_id`. This object doesn't include `phone`, even if your workspace uses phone numbers as an identifier; look for the person's `phone` attribute instead.",
      "required": [
        "email",
        "id",
        "cio_id"
      ],
      "properties": {
        "email": {
          "type": [
            "string",
            "null"
          ],
          "format": "email",
          "description": "A person's email address, if set."
        },
        "id": {
          "type": [
            "string",
            "null"
          ],
          "description": "A person's unique ID, if set. This is the same as the `customer_id` if present."
        },
        "cio_id": {
          "$ref": "#/$defs/cio_id"
        }
      }
    }
  }
}