Ortto People / Contacts API

Create or update one or more people (merge), retrieve people by query or by IDs, archive, delete, restore, and manage subscriptions and custom fields, with configurable merge strategies.

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