Emotive Open API

The public Emotive Open API for eCommerce integrations — track orders for attribution, opt a phone number out of SMS, and push custom events that can trigger an Emotive Flow. Authenticated with an Emotive-issued token in the Authorization header.

OpenAPI Specification

emotive-open-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Emotive Open API
  version: v1
  description: >-
    The public Emotive Open API for eCommerce integrations: order tracking, manual
    opt-outs, and custom events. Emotive documents these endpoints in prose on its
    knowledge base and Lists developer reference but publishes no machine-readable
    specification for them. This document was GENERATED by API Evangelist strictly
    from the request/response examples, header rules, body-parameter tables and HTTP
    status-code tables Emotive publishes on the pages listed in x-origin. No field,
    endpoint, or status code appears here that Emotive does not publish. Fields that
    Emotive documents only inside screenshots (the full Orders request/response
    parameter tables) are represented from the published cURL/Python payload example
    rather than from the images.
  contact:
    name: Emotive Support
    email: support@emotive.io
    url: https://help.emotive.io/
  x-origin:
  - url: https://help.emotive.io/docs/integrations/open-api-integration-orders
    format: documentation
    method: generated
    retrieved: '2026-08-13'
    note: Orders endpoint, Authorization scheme, required body parameters, full payload example, HTTP status-code tables.
  - url: https://help.emotive.io/docs/integrations/custom-site-api
    format: documentation
    method: generated
    retrieved: '2026-08-13'
    note: Authentication, content types, HTTP response-code conventions and the Orders API base URL.
  - url: https://emotive.gitbook.io/emotive-lists/reference/api-reference/unsubscribe
    format: documentation
    method: generated
    retrieved: '2026-08-13'
    note: Manual opt-out endpoint, headers, body and 200/400 response bodies.
  - url: https://emotive.gitbook.io/emotive-lists/reference/api-reference/custom-events
    format: documentation
    method: generated
    retrieved: '2026-08-13'
    note: Custom events endpoint, body parameter table and 200/401 response bodies.
servers:
- url: https://api.emotiveapp.co
  description: Emotive Open API (all three documented paths answer here; the apex host emotiveapp.co answers identically)
- url: https://emotiveapp.co
  description: Apex host named by the Lists developer reference for the opt-out and custom-event paths
security:
- TokenAuth: []
tags:
- name: Orders
  description: Order tracking for custom eCommerce sites.
- name: Opt-Outs
  description: Manual unsubscribe of a phone number.
- name: Custom Events
  description: Push arbitrary customer events that can trigger an Emotive Flow.
paths:
  /ecommerce/v1/orders/:
    post:
      tags: [Orders]
      operationId: createOrder
      summary: Track an order
      description: >-
        Send order data to Emotive so it can be attributed to an SMS subscriber.
        Orders sent without all required data, or with invalid values, return 400.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Order'
      responses:
        '200': { $ref: '#/components/responses/OK' }
        '201': { $ref: '#/components/responses/Created' }
        '292': { $ref: '#/components/responses/QueuedForExecution' }
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
        '403': { $ref: '#/components/responses/Forbidden' }
        '404': { $ref: '#/components/responses/NotFound' }
        '405': { $ref: '#/components/responses/MethodNotAllowed' }
        '409': { $ref: '#/components/responses/Conflict' }
        '412': { $ref: '#/components/responses/PreconditionFailed' }
        '413': { $ref: '#/components/responses/PayloadTooLarge' }
        '500': { $ref: '#/components/responses/InternalServerError' }
        '501': { $ref: '#/components/responses/NotImplemented' }
        '503': { $ref: '#/components/responses/ServiceUnavailable' }
  /ecommerce/v1/opt_outs/manual_opt_out/:
    post:
      tags: [Opt-Outs]
      operationId: manualOptOut
      summary: Unsubscribe a phone number
      description: Opt a subscriber out of SMS by phone number.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [phone_number]
              properties:
                phone_number:
                  type: string
                  description: E164 formatted subscriber phone number.
                  example: '+14132737194'
      responses:
        '200':
          description: Opt out request processed.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Message' }
              example: { message: Opt out request processed. }
        '400':
          description: Invalid phone number.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Message' }
              example: { message: Invalid phone number. }
  /campaign_engine/api/v1/custom_events/:
    post:
      tags: [Custom Events]
      operationId: createCustomEvent
      summary: Push a custom event
      description: >-
        Push a custom event for a subscriber. At least one of phone_number or email
        must be supplied to identify the subscriber. Custom events are consumed by a
        Flow (Experience) with a "Custom Event" trigger filtered on event_name.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomEvent'
      responses:
        '200':
          description: success
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Message' }
              example: { message: success }
        '400':
          description: Field validation error. Field-level errors are keyed by field name.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/FieldErrors' }
              example:
                event_name: ['This field is required.']
                event_datetime: ['This field is required.']
        '401':
          description: Invalid token.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Detail' }
              example: { detail: Invalid token. }
components:
  securitySchemes:
    TokenAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Encoded token authorization over HTTPS. The header value is the word "Token",
        a space, then the API key Emotive provides. Example: `Authorization: Token <api_token>`.
        Tokens are unique to an Emotive brand user; contact support@emotive.io or create a
        List Growth API signup flow to obtain one.
  responses:
    OK:
      description: OK
    Created:
      description: Created
    QueuedForExecution:
      description: Accepted (request accepted, and queued for execution)
    BadRequest:
      description: Bad Request (missing or invalid data provided). The response body contains an "error" attribute explaining what happened and how to correct it, if applicable.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
    Unauthorized:
      description: Unauthorized / Authentication Failure
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Detail' }
          example: { detail: Authentication credentials were not provided. }
    Forbidden:
      description: Forbidden
    NotFound:
      description: Resource not found
    MethodNotAllowed:
      description: Method not allowed
    Conflict:
      description: Conflict
    PreconditionFailed:
      description: Precondition failed
    PayloadTooLarge:
      description: Request entity too large
    InternalServerError:
      description: Internal server error
    NotImplemented:
      description: Not implemented
    ServiceUnavailable:
      description: Service unavailable
  schemas:
    Message:
      type: object
      properties:
        message: { type: string }
    Detail:
      type: object
      properties:
        detail: { type: string }
    Error:
      type: object
      properties:
        error: { type: string, description: Explains what happened and how to correct it, if applicable. }
    FieldErrors:
      type: object
      additionalProperties:
        type: array
        items: { type: string }
      description: Field-name keyed list of validation messages.
    CustomEvent:
      type: object
      required: [event_name, event_datetime]
      properties:
        phone_number: { type: string, description: E164 formatted subscriber phone number., example: '+14132737194' }
        email: { type: string }
        event_name: { type: string, description: 'Descriptive name for the custom event, eg: user-clicked', example: user-clicked }
        event_datetime: { type: string, description: ISO-8601 formatted timestamp. }
        properties:
          type: object
          description: key/value pairs of event properties
          additionalProperties: true
    Order:
      type: object
      required: [customer, line_items, total_price, order_id, order_date]
      properties:
        customer: { $ref: '#/components/schemas/Customer' }
        shipping_address: { $ref: '#/components/schemas/ShippingAddress' }
        line_items:
          type: array
          items: { $ref: '#/components/schemas/LineItem' }
        discount_codes: { type: string, example: TEST15 }
        total_price: { type: number, example: 0 }
        currency: { type: string, example: USD }
        order_id: { type: integer, example: 12346 }
        order_date: { type: string, description: 'Order timestamp, e.g. 2020-02-02 10:10:10 or 2020-02-02T10:10:10' }
        is_subscribed_order: { type: boolean }
        email_opt_in: { type: boolean }
        text_opt_in: { type: boolean }
        notes: { type: string }
        extra_data: { type: object, additionalProperties: true }
        customer_tags:
          type: array
          items: { type: string }
    Customer:
      type: object
      required: [phone]
      properties:
        id: { type: string }
        first_name: { type: string }
        last_name: { type: string }
        phone: { type: string, description: E164 formatted subscriber phone number., example: '+14132737194' }
        email: { type: string }
        notes: { type: string }
        extra_data: { type: object, additionalProperties: true }
    ShippingAddress:
      type: object
      properties:
        name: { type: string }
        address1: { type: string }
        address2: { type: string }
        city: { type: string }
        state_code: { type: string }
        zip: { type: string }
        country_code: { type: string }
        notes: { type: string }
        extra_data: { type: object, additionalProperties: true }
    LineItem:
      type: object
      required: [product, price]
      properties:
        product: { $ref: '#/components/schemas/Product' }
        collection: { $ref: '#/components/schemas/Collection' }
        variant: { $ref: '#/components/schemas/Variant' }
        price: { type: number }
        quantity: { type: integer }
        notes: { type: string }
        extra_data: { type: object, additionalProperties: true }
    Product:
      type: object
      required: [title, sku]
      properties:
        title: { type: string }
        sku: { type: string }
    Collection:
      type: object
      properties:
        title: { type: string }
        id: { type: string }
    Variant:
      type: object
      properties:
        id: { type: string }
        title: { type: string }