Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/softsync-ai:softsync-ai-messages-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Softsync Messages API
description: '## Introduction
The Softsync Platform API
This API lets you read and write your Softsync data from your own applications. Authenticate with a personal API key created in **Settings → API Keys**, sent as the `x-api-key` header.
**New here?** Read **Concepts** first, then **Authentication**, then **Quickstart: full cycle** — it walks the whole thing end to end. **Objects**, **Records**, **Groups & Views** and **Notes** cover each area in depth, and **Code Generation** shows how to turn this document into a typed client.
To try a request from this page, paste your API key into the **Authentication** panel on the right.
## Support
If you need help with API access or integration details, contact contact@softsync.ai.'
version: 0.1.0
contact: {}
servers: []
security:
- x-api-key: []
tags:
- name: Messages
paths:
/messages/integrations:
get:
operationId: getMessageIntegrations
parameters:
- name: x-workspace-id
in: header
description: Workspace ID
required: true
schema:
type: string
responses:
'200':
description: List of message integrations
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/IntegrationDto'
security:
- bearer: []
summary: Get available message integrations
tags:
- Messages
x-feature: messages
/messages/{id}:
get:
operationId: getMessageById
parameters:
- name: x-workspace-id
in: header
description: Workspace ID
required: true
schema:
type: string
- name: id
required: true
in: path
schema:
type: string
responses:
'200':
description: Message fetched successfully
content:
application/json:
schema:
$ref: '#/components/schemas/MessageDataDto'
security:
- bearer: []
summary: Get message by ID
tags:
- Messages
x-feature: messages
/messages/query:
post:
operationId: queryMessages
parameters:
- name: x-workspace-id
in: header
description: Workspace ID
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/QueryMessagesDto'
responses:
'200':
description: Messages fetched successfully
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedMessagesDto'
security:
- bearer: []
summary: Query messages with filters and pagination
tags:
- Messages
x-feature: messages
/messages/search:
post:
operationId: semanticSearch
parameters:
- name: x-workspace-id
in: header
description: Workspace ID
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SemanticSearchDto'
responses:
'200':
description: Search results retrieved successfully
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/MessageEmbeddingsDto'
security:
- bearer: []
summary: Semantic search across messages
tags:
- Messages
x-feature: messages
/messages/stats:
post:
operationId: getMessageStatistics
parameters:
- name: x-workspace-id
in: header
description: Workspace ID
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MessageLinkStatsQueryDto'
responses:
'200':
description: Message statistics retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/MessageLinkStatsDto'
security:
- bearer: []
summary: Get message link statistics
tags:
- Messages
x-feature: messages
/messages/multi-stats:
post:
operationId: getMultipleStatistics
parameters:
- name: x-workspace-id
in: header
description: Workspace ID
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MultipleMessageLinkStatsQueryDto'
responses:
'200':
description: Multiple message statistics retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/MultipleMessageLinkStatsDto'
security:
- bearer: []
summary: Get multiple message link statistics
tags:
- Messages
x-feature: messages
components:
schemas:
MultipleMessageLinkStatsItemDto:
type: object
properties:
name:
type: string
description: Name of the statistic
recordId:
type: string
description: Record ID to aggregate by
userId:
type: string
description: User ID to aggregate by
kinds:
description: Link kinds to count (e.g. mentioned_in)
type: array
items:
type: string
integrationTypes:
description: Integration types to filter by
type: array
items:
type: string
required:
- name
- kinds
MessageMessageLinkDto:
type: object
properties:
id:
type: string
linkedMessage:
$ref: '#/components/schemas/LinkedMessageDto'
kind:
type: string
required:
- id
- linkedMessage
- kind
MessageDataDto:
type: object
properties:
id:
type: string
integrationId:
type: string
integrationType:
type: string
content:
type: object
files:
type: array
items:
$ref: '#/components/schemas/FileAttachment'
metadata:
type: object
searchableText:
type: string
timestamp:
format: date-time
type: string
workspaceId:
type: string
description: The organization the message is in. Set only when reading across organizations.
createdAt:
format: date-time
type: string
recordLinks:
type: array
items:
$ref: '#/components/schemas/MessageRecordLinkDto'
userLinks:
type: array
items:
$ref: '#/components/schemas/MessageUserLinkDto'
messageLinks:
type: array
items:
$ref: '#/components/schemas/MessageMessageLinkDto'
required:
- id
- integrationId
- integrationType
- content
- files
- timestamp
- createdAt
- recordLinks
- userLinks
- messageLinks
LinkedMessageDto:
type: object
properties:
id:
type: string
integrationId:
type: string
integrationType:
type: string
content:
type: object
files:
type: array
items:
$ref: '#/components/schemas/FileAttachment'
metadata:
type: object
searchableText:
type: string
timestamp:
format: date-time
type: string
workspaceId:
type: string
description: The organization the message is in. Set only when reading across organizations.
createdAt:
format: date-time
type: string
recordLinks:
type: array
items:
$ref: '#/components/schemas/MessageRecordLinkDto'
userLinks:
type: array
items:
$ref: '#/components/schemas/MessageUserLinkDto'
required:
- id
- integrationId
- integrationType
- content
- files
- timestamp
- createdAt
- recordLinks
- userLinks
MessageQuerySortOrder:
type: string
enum:
- asc
- desc
description: 'Sort order by message timestamp (default: desc)'
PaginatedMessagesDto:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/MessageDataDto'
total:
type: number
description: Total number of items matching the query (may be approximate for cursor-based pagination)
page:
type: number
description: Current page number (for page-based pagination)
limit:
type: number
description: Number of items per page
totalPages:
type: number
description: Total number of pages (for page-based pagination)
hasNextPage:
type: boolean
description: Whether there is a next page
hasPreviousPage:
type: boolean
description: Whether there is a previous page (for page-based pagination)
nextCursor:
type: string
description: Cursor for next page (for cursor-based pagination)
prevCursor:
type: string
description: Cursor for previous page (for cursor-based pagination)
workspaces:
description: The organizations read, when reading across organizations
type: array
items:
$ref: '#/components/schemas/ScopedWorkspaceDto'
required:
- items
- limit
- hasNextPage
MessageLinkStatsQueryDto:
type: object
properties:
workspaces:
description: 'Which organizations to read: ''this'' (default), ''managed'' (every client organization of this one you are a member of), or a list of ids (this one and/or its client organizations). Across organizations, objects and fields are matched by API name, and each result carries its workspaceId.'
oneOf:
- type: string
enum:
- this
- managed
- type: array
items:
type: string
recordFilter:
description: 'Only messages linked to records that match these filters or to the records linked to them, as on a record''s page: emails with the people on deals in a given stage count as the deals'' emails. Combines with recordLinkFilter kinds; across organizations the object and fields are matched by API name.'
allOf:
- $ref: '#/components/schemas/RecordFilterDto'
integrationIds:
description: Exact integration IDs to filter by. Use this when a workflow already knows the concrete integration to query.
type: array
items:
type: string
integrationTypes:
description: Integration types to filter by (e.g. notes, private_notes). Only returns messages from accessible integrations.
type: array
items:
type: string
recordLinkFilter:
description: Filter by record links
allOf:
- $ref: '#/components/schemas/RecordLinkFilter'
userLinkFilter:
description: Filter by user links
allOf:
- $ref: '#/components/schemas/UserLinkFilter'
before:
type: string
description: Only include messages before this ISO timestamp
after:
type: string
description: Only include messages after this ISO timestamp
searchText:
type: string
description: Search text to filter messages by searchableText field (case-insensitive partial matching)
searchableText:
description: Structured searchableText tokens. Each entry matches either key:value or a raw value token.
type: array
items:
$ref: '#/components/schemas/SearchableTextTokenFilter'
limit:
type: number
description: 'Number of items per page (default: 20, max: 100)'
minimum: 1
maximum: 100
populateRecords:
type: boolean
description: 'Whether to populate record links (default: true)'
default: true
populateUsers:
type: boolean
description: 'Whether to populate user links (default: true)'
default: true
populateMessages:
type: boolean
description: 'Whether to populate message links (default: true)'
default: true
kinds:
description: Link kinds to count (e.g. mentioned_in)
type: array
items:
type: string
recordId:
type: string
description: Record ID to aggregate by
userId:
type: string
description: User ID to aggregate by
required:
- kinds
SearchableTextTokenFilter:
type: object
properties:
key:
type: string
description: Optional token key. When provided the search token is matched as key:value.
value:
type: string
description: Token value to match in searchableText. Without key this matches the raw value token.
required:
- value
ScopedWorkspaceDto:
type: object
properties:
id:
type: string
name:
type: string
required:
- id
- name
SemanticSearchDto:
type: object
properties:
workspaces:
description: 'Which organizations to read: ''this'' (default), ''managed'' (every client organization of this one you are a member of), or a list of ids (this one and/or its client organizations). Across organizations, objects and fields are matched by API name, and each result carries its workspaceId.'
oneOf:
- type: string
enum:
- this
- managed
- type: array
items:
type: string
recordFilter:
description: 'Only messages linked to records that match these filters or to the records linked to them, as on a record''s page: emails with the people on deals in a given stage count as the deals'' emails. Combines with recordLinkFilter kinds; across organizations the object and fields are matched by API name.'
allOf:
- $ref: '#/components/schemas/RecordFilterDto'
integrationIds:
description: Exact integration IDs to filter by. Use this when a workflow already knows the concrete integration to query.
type: array
items:
type: string
integrationTypes:
description: Integration types to filter by (e.g. notes, private_notes). Only returns messages from accessible integrations.
type: array
items:
type: string
recordLinkFilter:
description: Filter by record links
allOf:
- $ref: '#/components/schemas/RecordLinkFilter'
userLinkFilter:
description: Filter by user links
allOf:
- $ref: '#/components/schemas/UserLinkFilter'
before:
type: string
description: Only include messages before this ISO timestamp
after:
type: string
description: Only include messages after this ISO timestamp
searchText:
type: string
description: Search text to filter messages by searchableText field (case-insensitive partial matching)
searchableText:
description: Structured searchableText tokens. Each entry matches either key:value or a raw value token.
type: array
items:
$ref: '#/components/schemas/SearchableTextTokenFilter'
limit:
type: number
description: 'Number of items per page (default: 20, max: 100)'
minimum: 1
maximum: 100
populateRecords:
type: boolean
description: 'Whether to populate record links (default: true)'
default: true
populateUsers:
type: boolean
description: 'Whether to populate user links (default: true)'
default: true
populateMessages:
type: boolean
description: 'Whether to populate message links (default: true)'
default: true
query:
type: string
description: Search query text
sort:
description: Re-order the semantically matched results by message timestamp. Only re-orders the matches the query already selected — it does not widen the search. Omit to keep relevance order.
allOf:
- $ref: '#/components/schemas/MessageQuerySortOrder'
required:
- query
RecordMetadata:
type: object
properties:
viewOrders:
type: object
additionalProperties:
type: number
description: Orders in different views (viewId -> order)
avatarUrl:
type: string
description: Avatar file path stored in record metadata
formulaOverrides:
description: Calculated-default fields a person typed over; they are no longer recalculated
type: array
items:
type: string
ruleIssues:
type: array
items:
type: object
description: Rules this record breaks, saved by a change that may not be refused (e.g. a public booking). Cleared by the next save that passes.
source:
type: object
additionalProperties: true
description: The feature that made this record when no person did (a booking page, a form…)
MessageEmbeddingsDto:
type: object
properties:
id:
type: string
chunkIndex:
type: number
text:
type: string
metadata:
type: object
isMainContent:
type: boolean
fileId:
type: string
createdAt:
type: string
updatedAt:
type: string
message:
$ref: '#/components/schemas/MessageDataDto'
required:
- id
- chunkIndex
- text
- isMainContent
- createdAt
- updatedAt
- message
MultipleMessageLinkStatsDto:
type: object
properties:
stats:
type: array
items:
$ref: '#/components/schemas/MultipleMessageLinkStatsResultDto'
required:
- stats
FilterOperator:
type: string
enum:
- eq
- ne
- gt
- gte
- lt
- lte
- contains
- in
- is_empty
- is_not_empty
description: 'Filter operator: eq (equals), ne (not equals), gt (greater than), gte (greater than or equal), lt (less than), lte (less than or equal), contains (substring match), in (value exists in array), is_empty (field has no value), is_not_empty (field has value)'
MessageRecordLinkDto:
type: object
properties:
id:
type: string
record:
$ref: '#/components/schemas/RecordInfoDto'
kind:
type: string
required:
- id
- record
- kind
MultipleMessageLinkStatsResultDto:
type: object
properties:
name:
type: string
description: Name of the statistic
kinds:
description: Link kind(s) used for counting
type: array
items:
type: string
count:
type: number
description: Number of messages matching the filters
required:
- name
- kinds
- count
MessageLinkStatsDto:
type: object
properties:
kinds:
description: Link kind(s) used for counting
type: array
items:
type: string
count:
type: number
description: Number of messages matching the filters
required:
- kinds
- count
IntegrationDto:
type: object
properties:
id:
type: string
description: Integration identifier
type:
type: string
description: Integration type (e.g. notes, private_notes)
visibility:
type: string
description: Integration visibility (private or shared)
ownerId:
type: string
description: Owner user ID for private integrations
canManage:
type: boolean
description: Whether the caller connected it and may change or disconnect it; false for a mailbox a teammate shared with them
metadata:
type: object
config:
type: object
required:
- id
- type
- visibility
- canManage
MultipleMessageLinkStatsQueryDto:
type: object
properties:
stats:
description: Array of statistics queries
type: array
items:
$ref: '#/components/schemas/MultipleMessageLinkStatsItemDto'
required:
- stats
FilterCondition:
type: string
enum:
- and
- or
description: Logical condition to chain with the previous filter or group (AND/OR). Defaults to AND if not specified. The first filter in the array ignores this field. For grouped filters, this determines how the group connects to the previous filter/group.
FileAttachment:
type: object
properties:
id:
type: string
path:
type: string
fileName:
type: string
fileSize:
type: number
mime:
type: string
isInline:
type: boolean
contentId:
type: string
url:
type: string
required:
- id
- path
- fileName
- fileSize
- mime
UserInfoDto:
type: object
properties:
id:
type: string
email:
type: string
firstName:
type: string
lastName:
type: string
avatarUrl:
type: string
required:
- id
- email
MessageUserLinkDto:
type: object
properties:
id:
type: string
user:
$ref: '#/components/schemas/UserInfoDto'
kind:
type: string
required:
- id
- user
- kind
SystemField:
type: string
enum:
- __system_created_at
- __system_updated_at
- __system_created_by
- __system_last_interaction_at
- __system_last_sent_at
- __system_last_received_at
FieldQueryFilter:
type: object
properties:
fieldId:
description: Field ID to filter on
example: field_id_123
oneOf:
- type: string
- $ref: '#/components/schemas/SystemField'
operator:
description: 'Filter operator: eq (equals), ne (not equals), gt (greater than), gte (greater than or equal), lt (less than), lte (less than or equal), contains (substring match), in (value exists in array), is_empty (field has no value), is_not_empty (field has value)'
example: eq
allOf:
- $ref: '#/components/schemas/FilterOperator'
value:
description: Value to compare against. Type should match the field type and operator requirements.
example: 123
oneOf:
- type: string
- type: number
- type: boolean
- type: array
condition:
description: Logical condition to chain with the previous filter or group (AND/OR). Defaults to AND if not specified. The first filter in the array ignores this field. For grouped filters, this determines how the group connects to the previous filter/group.
example: and
allOf:
- $ref: '#/components/schemas/FilterCondition'
groupId:
type: string
description: 'Optional group identifier. Filters sharing the same groupId are wrapped in parentheses and evaluated together as a logical unit. Filters within a group are chained using their individual condition fields. Groups are connected to each other using the condition field of the first filter in each subsequent group. Use grouping to create complex expressions like: (A OR B) AND (C OR D).'
example: group1
required:
- fieldId
- operator
- value
RecordInfoDto:
type: object
properties:
id:
type: string
table:
type: string
groups:
type: array
items:
type: string
data:
type: object
description: Raw data keyed by field ID
metadata:
$ref: '#/components/schemas/RecordMetadata'
createdAt:
format: date-time
type: string
updatedAt:
format: date-time
type: string
createdBy:
type: string
required:
- id
- table
- data
- createdAt
- updatedAt
QueryMessagesDto:
type: object
properties:
workspaces:
description: 'Which organizations to read: ''this'' (default), ''managed'' (every client organization of this one you are a member of), or a list of ids (this one and/or its client organizations). Across organizations, objects and fields are matched by API name, and each result carries its workspaceId.'
oneOf:
- type: string
enum:
- this
- managed
- type: array
items:
type: string
recordFilter:
description: 'Only messages linked to records that match these filters or to the records linked to them, as on a record''s page: emails with the people on deals in a given stage count as the deals'' emails. Combines with recordLinkFilter kinds; across organizations the object and fields are matched by API name.'
allOf:
- $ref: '#/components/schemas/RecordFilterDto'
integrationIds:
description: Exact integration IDs to filter by. Use this when a workflow already knows the concrete integration to query.
type: array
items:
type: string
integrationTypes:
description: Integration types to filter by (e.g. notes, private_notes). Only returns messages from accessible integrations.
type: array
items:
type: string
recordLinkFilter:
description: Filter by record links
allOf:
- $ref: '#/components/schemas/RecordLinkFilter'
userLinkFilter:
description: Filter by user links
allOf:
- $ref: '#/components/schemas/UserLinkFilter'
before:
type: string
description: Only include messages before this ISO timestamp
after:
type: string
description: Only include messages after this ISO timestamp
searchText:
type: string
description: Search text to filter messages by searchableText field (case-insensitive partial matching)
searchableText:
description: Structured searchableText tokens. Each entry matches either key:value or a raw value token.
type: array
items:
$ref: '#/components/schemas/SearchableTextTokenFilter'
limit:
type: number
description: 'Number of items per page (default: 20, max: 100)'
minimum: 1
maximum: 100
populateRecords:
type: boolean
description: 'Whether to populate record links (default: true)'
default: true
populateUsers:
type: boolean
description: 'Whether to populate user links (default: true)'
default: true
populateMessages:
type: boolean
description: 'Whether to populate message links (default: true)'
default: true
sort:
description: 'Sort order by message timestamp (default: desc)'
default: desc
allOf:
- $ref: '#/components/schemas/MessageQuerySortOrder'
cursor:
type: string
description: Cursor for pagination (base64 encoded timestamp:id). If provided, page parameter is ignored.
direction:
type: string
description: Only messages that came in (inbound) or went out (outbound). With onePerConversation it says who wrote last.
enum:
- inbound
- outbound
excludeBulk:
type: boolean
description: 'Leave out bulk mail: newsletters, mailing lists and automatic messages, as their headers mark them.'
onePerConversation:
type: boolean
description: Only the newest message of each conversation or email thread.
RecordLinkFilter:
type: object
properties:
recordIds:
description: Record IDs to filter by
type: array
items:
type: string
kinds:
description: Link kinds to filter by (e.g. attached, mentioned_in). If omitted, all kinds are included.
type: array
items:
type: string
required:
- recordIds
RecordFilterDto:
type: object
properties:
tableId:
type: string
description: The object (table) the records belong to
fieldFilters:
description: The same filters record search takes
type: array
items:
$ref: '#/components/schemas/FieldQueryFilter'
required:
- tableId
UserLinkFilter:
type: object
properties:
userIds:
description: User IDs to filter by
type: array
items:
type: string
kinds:
description: Link kinds to filter by (e.g. owner, mentioned_in). If omitted, all kinds are included.
type: array
items:
type: string
required:
- userIds
securitySchemes:
bearer:
scheme: bearer
bearerFormat: JWT
type: http
x-api-key:
type: apiKey
in: header
name: x-api-key