Ortto Transactional Email API

Send transactional (or, with non_transactional set, marketing) email and SMS via a single POST, with support for up to 5 base64-encoded attachments; the endpoint returns a 202 on acceptance.

OpenAPI Specification

ortto-openapi.yml Raw ↑
openapi: 3.0.1
info:
  title: Ortto API
  description: >-
    REST API for Ortto (formerly Autopilot), a marketing automation, customer
    data platform (CDP), and analytics product. The API lets applications
    create and update people/contacts and accounts, send custom activity
    events, manage tags, retrieve campaign and asset reports, and send
    transactional email and SMS. Every request is authenticated with a custom
    API key supplied in the X-Api-Key header. The default service endpoint is
    https://api.ap3api.com/v1; customers in Australia or Europe use
    https://api.au.ap3api.com/v1 or https://api.eu.ap3api.com/v1 respectively.
  termsOfService: https://ortto.com/terms-of-service/
  contact:
    name: Ortto Support
    url: https://help.ortto.com/
  version: '1.0'
servers:
  - url: https://api.ap3api.com/v1
    description: Default service endpoint
  - url: https://api.au.ap3api.com/v1
    description: Australia service endpoint
  - url: https://api.eu.ap3api.com/v1
    description: Europe service endpoint
security:
  - ApiKeyAuth: []
tags:
  - name: People
    description: Create, update, retrieve, and manage people (contacts).
  - name: Accounts
    description: Create, update, retrieve, and manage accounts (organizations).
  - name: Activities
    description: Send custom activity events and manage activity definitions.
  - name: Campaigns
    description: Retrieve campaigns, reports, and assets.
  - name: Tags
    description: Retrieve account tags.
  - name: Transactional
    description: Send transactional email and SMS.
paths:
  /person/merge:
    post:
      operationId: mergePeople
      tags:
        - People
      summary: Create or update one or more people (merge)
      description: >-
        Creates or updates up to 100 people in a single request. Matching of
        existing records is controlled with merge_by, merge_strategy, and
        find_strategy.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PersonMergeRequest'
      responses:
        '200':
          description: People created or updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonMergeResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /person/get:
    post:
      operationId: getPeople
      tags:
        - People
      summary: Retrieve one or more people (get)
      description: >-
        Retrieves people matching a filter, with the requested fields, sort
        order, limit, and offset for pagination.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PersonGetRequest'
      responses:
        '200':
          description: Matching people.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonGetResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /person/get-by-ids:
    post:
      operationId: getPeopleByIds
      tags:
        - People
      summary: Retrieve people by their Ortto IDs
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                contact_ids:
                  type: array
                  items:
                    type: string
                fields:
                  type: array
                  items:
                    type: string
      responses:
        '200':
          description: Matching people.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonGetResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /person/delete:
    post:
      operationId: deletePeople
      tags:
        - People
      summary: Delete one or more people
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                people:
                  type: array
                  items:
                    type: object
                    properties:
                      contact_id:
                        type: string
      responses:
        '200':
          description: People deleted.
        '401':
          $ref: '#/components/responses/Unauthorized'
  /accounts/merge:
    post:
      operationId: mergeAccounts
      tags:
        - Accounts
      summary: Create or update one or more accounts (merge)
      description: >-
        Creates or updates accounts (previously called organizations) using the
        same merge semantics as people.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                accounts:
                  type: array
                  items:
                    type: object
                    properties:
                      fields:
                        type: object
                        additionalProperties: true
                merge_by:
                  type: array
                  items:
                    type: string
                merge_strategy:
                  type: integer
      responses:
        '200':
          description: Accounts created or updated.
        '401':
          $ref: '#/components/responses/Unauthorized'
  /activities/create:
    post:
      operationId: createActivities
      tags:
        - Activities
      summary: Create one or more custom activity events
      description: >-
        Sends up to 100 custom activity events in a single payload (max 2 MB).
        Each activity references a custom activity definition and may create or
        update the associated person via merge_by or person_id.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActivitiesCreateRequest'
      responses:
        '200':
          description: Activities accepted.
        '401':
          $ref: '#/components/responses/Unauthorized'
  /tags/get:
    post:
      operationId: getTags
      tags:
        - Tags
      summary: Retrieve a list of tags
      description: >-
        Retrieves the tags configured on the account. An empty body returns all
        tags; an optional search term filters the result.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                q:
                  type: string
                  description: Optional search term to filter tags.
      responses:
        '200':
          description: List of tags.
          content:
            application/json:
              schema:
                type: object
                properties:
                  tags:
                    type: array
                    items:
                      type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
  /campaign/calendar:
    post:
      operationId: getCampaignCalendar
      tags:
        - Campaigns
      summary: Retrieve campaigns by time period
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  description: Campaign type, e.g. journey.
                state:
                  type: string
                folder_id:
                  type: string
                q:
                  type: string
                sort_order:
                  type: string
                limit:
                  type: integer
      responses:
        '200':
          description: Matching campaigns.
        '401':
          $ref: '#/components/responses/Unauthorized'
  /campaign/reports/get:
    post:
      operationId: getCampaignReport
      tags:
        - Campaigns
      summary: Retrieve a campaign or asset report
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                campaign_id:
                  type: string
                asset_id:
                  type: string
      responses:
        '200':
          description: Campaign or asset report.
        '401':
          $ref: '#/components/responses/Unauthorized'
  /transactional/send:
    post:
      operationId: sendTransactionalEmail
      tags:
        - Transactional
      summary: Send a transactional email
      description: >-
        Sends a transactional email. Set non_transactional to true to send as a
        marketing email. Up to 5 base64-encoded attachments are supported. A
        successful request returns a 202 Accepted.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransactionalSendRequest'
      responses:
        '202':
          description: Request received and accepted for delivery.
        '401':
          $ref: '#/components/responses/Unauthorized'
  /transactional/send-sms:
    post:
      operationId: sendTransactionalSms
      tags:
        - Transactional
      summary: Send a transactional SMS
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                sms_id:
                  type: string
                merge_by:
                  type: array
                  items:
                    type: string
                people:
                  type: array
                  items:
                    type: object
                    additionalProperties: true
      responses:
        '202':
          description: Request received and accepted for delivery.
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key
      description: >-
        Custom private API key configured in Ortto under Settings, supplied on
        every request in the X-Api-Key header.
  responses:
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    PersonMergeRequest:
      type: object
      required:
        - people
        - merge_by
      properties:
        people:
          type: array
          maxItems: 100
          items:
            $ref: '#/components/schemas/PersonInput'
        merge_by:
          type: array
          description: Up to 3 field IDs used to identify existing records.
          maxItems: 3
          items:
            type: string
        merge_strategy:
          type: integer
          description: 1 = append only, 2 = overwrite existing, 3 = ignore.
          enum: [1, 2, 3]
        find_strategy:
          type: integer
          description: 0 = any, 1 = sequential, 2 = all.
          enum: [0, 1, 2]
        async:
          type: boolean
          description: Queue processing when true; recommended for large batches.
        skip_non_existing:
          type: boolean
          description: When true, only updates existing records.
        suppression_list_field_id:
          type: string
    PersonInput:
      type: object
      properties:
        fields:
          type: object
          description: Map of field IDs to values for the person.
          additionalProperties: true
        location:
          type: object
          additionalProperties: true
        tags:
          type: array
          items:
            type: string
        unset_tags:
          type: array
          items:
            type: string
    PersonMergeResponse:
      type: object
      properties:
        people:
          type: array
          items:
            type: object
            properties:
              person_id:
                type: string
              status:
                type: string
                description: e.g. created, updated, or suppressed.
    PersonGetRequest:
      type: object
      properties:
        limit:
          type: integer
        offset:
          type: integer
        sort_by_field_id:
          type: string
        sort_order:
          type: string
          enum: [asc, desc]
        fields:
          type: array
          items:
            type: string
        filter:
          type: object
          additionalProperties: true
    PersonGetResponse:
      type: object
      properties:
        contacts:
          type: array
          items:
            type: object
            additionalProperties: true
        offset:
          type: integer
        has_more:
          type: boolean
    ActivitiesCreateRequest:
      type: object
      required:
        - activities
      properties:
        activities:
          type: array
          maxItems: 100
          items:
            type: object
            properties:
              activity_id:
                type: string
              person_id:
                type: string
              attributes:
                type: object
                additionalProperties: true
              fields:
                type: object
                additionalProperties: true
              location:
                type: object
                additionalProperties: true
        merge_by:
          type: array
          items:
            type: string
    TransactionalSendRequest:
      type: object
      properties:
        email_id:
          type: string
          description: ID of the transactional email asset to send.
        non_transactional:
          type: boolean
          description: When true, the message is sent as a marketing email.
        merge_by:
          type: array
          items:
            type: string
        people:
          type: array
          items:
            type: object
            properties:
              fields:
                type: object
                additionalProperties: true
        html_body:
          type: string
        subject:
          type: string
        attachments:
          type: array
          maxItems: 5
          items:
            type: object
            properties:
              name:
                type: string
              data:
                type: string
                description: Base64-encoded file contents.
              mime_type:
                type: string
    Error:
      type: object
      properties:
        status:
          type: string
        error:
          type: string