Ortto Custom Activities API
Send up to 100 custom activity events per request (2 MB max) and manage activity definitions, optionally creating or updating the associated person via merge_by or person_id.
Send up to 100 custom activity events per request (2 MB max) and manage activity definitions, optionally creating or updating the associated person via merge_by or person_id.
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