Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Instasent product Registration API
description: '### Overview
The Instasent Product API provides a comprehensive set of tools for managing **organizations** and **projects** within the Instasent platform. This API is designed to help businesses organize customer data, manage team permissions, and set up projects for targeted marketing and customer engagement. ### What is the Product API? The Product API is Instasent''s primary management API for high-level entities and operations. It provides comprehensive tools for managing your organization''s customer data platform, from initial setup to ongoing operations. > **NOTE**:
> - To access the Product API you need a Product Token and your Project UID, you can get them in your project settings. **Core Purpose**: The Product API enables you to:
- **Manage Organizations & Projects**: View organization information, create and configure projects, and manage project-level settings
- **Configure Data Sources**: Create and manage API data sources that serve as entry points for customer data
- **Access Unified Audience Data**: Query, search, and retrieve contacts from your project''s unified audience, where data from multiple sources is automatically merged
- **Track Customer Events**: Search and analyze customer interaction events to understand behavior patterns
- **Manage Segments**: View and work with audience segments for targeted marketing
- **Monitor Campaigns & Automations**: Access campaign and automation details, configurations, and status
- **Send Direct Messages**: Create and send direct SMS messages to audience contacts, and manage SMS senders
- **Ingest Data**: Push contacts and events to data sources via the Ingest API (integrated into the Product API)
**Key Entities**:
- **Organizations**: Represent companies using Instasent. Each organization has its own settings, billing information, user accounts, and API tokens. Organizations can contain multiple projects. - **Projects**: Isolated environments within an organization where customer data, contacts, events, segments, campaigns, and automations are managed. Projects allow you to organize different brands, customer segments, or marketing initiatives separately. - **Data Sources**: Collections of contacts and events that feed into a project. Multiple data sources can contribute to a single project''s unified audience. - **Contacts**: Individual records representing customers, leads, or audience members. Contacts from different data sources are automatically merged into a unified `Audience Contact` when they share matching unique identifiers. - **Events**: Immutable records of customer interactions, such as purchases, page views, email opens, or any custom activity. Events enrich contact profiles and can trigger automations. ### Key Features and Benefits
The Product API empowers organizations by providing comprehensive tools for customer data management and marketing automation:
1. **Data Ingestion & Management**:
- Create and manage API data sources for ingesting contacts and events
- Push contacts and events to data sources via the Ingest API
- View datasource statistics and stream specifications
- Delete contacts from data sources when needed
2. **Unified Audience Management**:
- Access a project''s unified audience where contacts from multiple data sources are automatically merged
- Search and filter contacts using powerful QueryFilter syntax
- Scroll through large contact lists with cursor-based pagination
- Retrieve contacts by ID, user identifier, phone number, or email address
- View contact events and interaction history
3. **Event Tracking & Analysis**:
- Search and filter audience events using the Event Filtering system
- Scroll through event history with pagination support
- Access event data to understand customer behavior and interactions
4. **Segmentation & Targeting**:
- View and manage audience segments (static and dynamic)
- Scroll contacts within specific segments
- Use segments for targeted marketing campaigns
5.'
version: 2.0.0
contact:
email: dev@instasent.com
url: https://instasent.com
name: Instasent
license:
name: Instasent
url: https://www.instasent.com/aviso-legal
servers:
- url: https://api.instasent.com/v1
description: Instasent product API
security:
- BearerAuth: []
- OAuth2: []
tags:
- name: Registration
description: 'A country''s registration paperwork for one sender: sign a letter, allowlist a
verifier, email an operator. Not the setup checklist, which is product
configuration and lives under `readiness` — a project can be fully ready and
still owe one country a signed letter.
Its own tag rather than a channel''s because the paperwork hangs off the
channel, not the country, and both SMS and RCS answer the same shape. Filing
it under `rcs-sender` would publish the SMS endpoint under an RCS heading.'
paths:
/project/{project}/channel/{channel}/sender/{id}/register/{country}/checklist:
get:
summary: Registration checklist for one country
description: 'What a country''s registration still asks of this customer for one
sender, and what is already done.
Each step comes back in one of three states, and only one of them is
stored anywhere: `completed` is recorded, while `disabled` ("an
earlier step it depends on is not done") is derived from the
dependency graph. Absence of a mark means pending; there is no third
value.
**`disabled: true` is not "pending on the customer".** It is a step
they cannot start yet, and offering it as an action sends them to do
something that will be rejected. `waitingOn` says whose move it is.
**`available: false` is not "nothing to do".** It means the country
requirements could not be read. Never present the two the same way.
Steps hang off the channel rather than the country, so both channels
answer the same shape. Today only RCS countries publish steps, and
an SMS request returns an empty list with `available: true`.
**One row is not paperwork**: when we charge for the registration,
the register''s payment comes LAST, with `kind: payment` and the
payment itself in `payment`. It is there even when `available` is
false, because the payment is ours and not the country''s. It is
done when the payment is executed, nobody marks it, it never blocks
the registration, and a canceled payment is not listed. While it is
open the same debt is also the attention item
`registration-payment-pending`.
**Required Scope**: `PROJECT_READ`'
tags:
- Registration
parameters:
- $ref: '#/components/parameters/ProjectPath'
- name: channel
in: path
required: true
description: sms or rcs.
schema:
type: string
enum:
- sms
- rcs
- name: id
in: path
required: true
description: The sender id.
schema:
type: string
- name: country
in: path
required: true
description: ISO 3166-1 alpha-2, uppercase.
schema:
type: string
pattern: ^[A-Z]{2}$
- name: lang
in: query
required: false
description: Language of the step titles. Defaults to en.
schema:
type: string
enum:
- en
- es
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
entity:
$ref: '#/components/schemas/ResponseRegistrationChecklist'
required:
- entity
'401':
$ref: '#/components/responses/UnauthorizedError'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimitError'
'500':
$ref: '#/components/responses/InternalError'
operationId: getProjectByProjectChannelByChannelSenderByIdRegisterByCountryChecklist
x-operation-id-source: derived
/project/{project}/channel/registration-progress:
get:
summary: Registration progress across the project
description: 'One row of counts per sender and country **that has recorded
paperwork**, in a single call.
This answers the question that comes before the per-country
checklist and that nothing else can: which countries to ask about
at all. Most destinations record no steps, so calling the checklist
endpoint per register is a guess.
A register whose country publishes nothing is **left out**, not
returned as zeroes: "nothing to do here" and "nothing is written up
for this country" are different answers, and a row of zeroes says
the first while meaning the second.
`actionable` is what the customer can act on right now. It is the
number worth leading with; `blocked` is waiting on an earlier step
and is not something to ask them for.
`metadata.available` is `false` when the country requirements could
not be read, which is not the same as having nothing pending.
**Required Scope**: `PROJECT_READ`'
tags:
- Registration
parameters:
- $ref: '#/components/parameters/ProjectPath'
- name: channel
in: query
required: false
description: Narrow to one channel. Omitted returns both.
schema:
type: string
enum:
- sms
- rcs
- name: lang
in: query
required: false
description: Language of any text. Defaults to en.
schema:
type: string
enum:
- en
- es
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
entities:
type: array
items:
$ref: '#/components/schemas/ResponseRegistrationProgressItem'
metadata:
type: object
properties:
count:
type: integer
available:
type: boolean
description: 'False when the country requirements could not be
read. An empty `entities` with this false means we
could not look, not that nothing is pending.
'
required:
- entities
'401':
$ref: '#/components/responses/UnauthorizedError'
'429':
$ref: '#/components/responses/RateLimitError'
'500':
$ref: '#/components/responses/InternalError'
operationId: getProjectByProjectChannelRegistrationProgress
x-operation-id-source: derived
components:
schemas:
ResponseErrorDetail:
type: object
properties:
title:
type: string
status:
type: integer
detail:
type: string
required:
- title
- status
- detail
x-stoplight:
id: v3njemo17ya0e
ResponseRegistrationChecklist:
type: object
description: 'One country''s registration for one sender: what its paperwork asks
of the customer, and how far along it is.
'
properties:
country:
type: string
description: ISO 3166-1 alpha-2.
channel:
type: string
enum:
- sms
- rcs
available:
type: boolean
description: 'False means the country requirements could not be read. It is
NOT the same as the country asking for nothing, and must never
be presented as "nothing left to do".
'
steps:
type: array
items:
$ref: '#/components/schemas/ResponseRegistrationStep'
register:
type: object
description: 'The register''s own identity. On RCS this carries the
`externalAgentId` that several operators ask the customer to
quote verbatim in the paperwork they send; it is null until
the agent has been filed.
'
additionalProperties:
type:
- string
- 'null'
required:
- country
- channel
- steps
- available
ResponseErrorMessage:
type: object
properties:
message:
type: string
code:
type: integer
required:
- message
x-stoplight:
id: nzjbrnkttcnxo
ResponseRegistrationStep:
type: object
description: 'One step of a country''s registration. Three states, of which only
one is stored: `completed` is recorded, `disabled` is derived from
the dependency graph, and neither means the step can be acted on now.
'
properties:
key:
type: string
description: 'Stable forever, and the identity progress is recorded against.
Reused across countries when it is the same concept. Show the
title to a person, never this. `payment` is reserved for the
payment row.
'
kind:
type: string
enum:
- payment
description: 'Present only on the payment row, the register''s payment for
the registration, always the last row. Absent on every
paperwork step.
'
title:
type: string
actor:
type: string
enum:
- customer
- instasent
- third-party
description: Whose step it is.
completed:
type: boolean
disabled:
type: boolean
description: 'An earlier step it depends on is not done. Do not offer it as
an action: it is not "pending on the customer", it is not
startable.
'
isBlocker:
type: boolean
description: 'True on every paperwork step: a country''s paperwork is not
optional. False on the payment row, which never holds the
registration back.
'
skipped:
type: boolean
skippable:
type: boolean
description: Always false. These cannot be dismissed.
waitingOn:
type:
- string
- 'null'
enum:
- customer
- instasent
- third-party
- submission
- null
description: 'Whose move it is right now: this step''s actor once it is
startable, otherwise the actor of whatever is blocking it.
`submission` means the registration has not been submitted
yet. Null only on the payment row once nothing is owed.
'
completedAt:
type:
- string
- 'null'
format: date-time
description: 'When it was done. On the payment row, when the payment was
executed, and null while it is not.
'
payment:
type: object
description: 'Only on the payment row: the payment, the same summary the
register serves as `relatedChargeRequest`. `amount` is before
taxes and `finalAmount` with them. `publicReference` is null
on a wire-transfer draft that has not got one yet.
`paymentLink` is null when the payment has no link, and
`active: false` once it can no longer be paid.
'
properties:
id:
type: string
publicReference:
type:
- string
- 'null'
status:
type: string
description: 'The payment status: executed means paid.'
chargeTitle:
type: string
example: sender.register
amount:
type:
- number
- 'null'
finalAmount:
type: number
currency:
type: string
example: EUR
paymentLink:
type:
- object
- 'null'
properties:
url:
type: string
active:
type: boolean
createdAt:
type:
- string
- 'null'
format: date-time
executedAt:
type:
- string
- 'null'
format: date-time
customerCanMark:
type: boolean
description: 'Whether the customer may tick this one themselves. True only
for their own steps; the backend refuses the rest regardless
of what a screen offers.
'
required:
- key
- title
- actor
- completed
- disabled
ResponseRegistrationProgressItem:
type: object
description: 'One sender and country with registration paperwork still outstanding.
Registers that are accepted, rejected or archived are not listed:
the first has nothing left to chase and the second is a different
conversation, which the attention endpoint owns.
'
properties:
senderId:
type: string
senderName:
type:
- string
- 'null'
description: The RCS agent name, or the SMS alias.
country:
type: string
channel:
type: string
enum:
- sms
- rcs
total:
type: integer
done:
type: integer
blocked:
type: integer
description: 'Held up by an earlier step. Not something to ask the customer
for yet.
'
actionable:
type: integer
description: 'Can be acted on right now. The number worth leading with.
'
waitingOn:
type:
- string
- 'null'
description: Null when nothing is left.
required:
- senderId
- country
- channel
- total
- done
responses:
NotFound:
description: Resource can't be found
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseErrorDetail'
UnauthorizedError:
description: You are missing or using bad credentials
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseErrorMessage'
InternalError:
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseErrorMessage'
RateLimitError:
description: You reached your endpoint rate limit
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseErrorMessage'
parameters:
ProjectPath:
name: project
in: path
description: Project UID (e.g., 'my-project-123')
required: true
schema:
type: string
securitySchemes:
BearerAuth:
description: Token with permissions to access the endpoint
type: http
scheme: bearer
OAuth2:
description: 'OAuth 2.1 Authorization Code flow with PKCE, for applications that act in a
user''s name instead of using a token the user pasted. The resulting access
token is an ordinary Product API bearer token (`isoa_` prefix) with a
24-hour lifetime, refreshed through `POST /oauth/token`.
Register the client first with `POST /oauth/register`, or use a `client_id`
issued by Instasent. PKCE is mandatory and only `S256` is accepted; there is
no client secret. Discover these URLs at runtime from
`/.well-known/oauth-authorization-server` rather than hard-coding them. All
three are on this API host; the authorization URL is a browser redirect that
hands the user to the dashboard''s consent screen.
The scopes below are the same product permissions the API returns in
`GET /` and the dashboard shows when creating a token. Which of them a
client may be granted depends on its lane: MCP clients are limited to a
curated, agent-safe subset, while API clients may be offered the full set.
The final grant is always intersected with the authorizing user''s roles and
the organization''s plan.
'
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://api.instasent.com/oauth/authorize
tokenUrl: https://api.instasent.com/oauth/token
refreshUrl: https://api.instasent.com/oauth/token
scopes:
ACCOUNT_READ: Read access to organization account details and funds
PROJECT_DATASOURCE_READ: Read-only access to datasources
PROJECT_DATASOURCE_WRITE: Create and modify datasources
PROJECT_AUDIENCE_READ: Read access to audience contacts
PROJECT_AUDIENCE_WRITE: Write access to audience contacts
PROJECT_AUDIENCE_LIST: List and scroll audience contacts
PROJECT_AUDIENCE_DATA_BASIC: Access to basic contact data
PROJECT_AUDIENCE_DATA_FULL: Access to full contact data
PROJECT_AUDIENCE_DATA_EVENTS: Access to audience events
PROJECT_AGGREGATIONS: Access to audience and event aggregations
PROJECT_SEGMENT_WRITE: Save an audience filter as a segment
PROJECT_CAMPAIGN_READ: Read access to campaigns
PROJECT_CAMPAIGN_WRITE: Create a campaign draft
PROJECT_AUTOMATION_READ: Read access to automations
PROJECT_DIRECT_READ: Messaging read access
PROJECT_DIRECT_WRITE: Messaging write access
x-stoplight:
id: xl7ao4m61duhz