Run a mutation
Sequin makes it easy to write changes back to upstream APIs. Most collections that Sequin syncs are mutable. To create a record in a collection or mutate an existing one, you can use Sequin’s Record Mutation API.
For write requests that don’t map cleanly to a collection mutation, you can use Sequin’s API proxy.
Record Mutation API
The Record Mutation API lets you mutate one or more records synchronously:
POST /v1/mutations/run
For creates and updates, you’ll send Sequin a partial record. For creates, the partial record contains only the data
key:
{
"data": {
"FirstName": "Paul",
"LastName": "Atreides",
"Email": "paul@arrakis.org"
}
}
For updates, the partial record contains the upstream_id
and data
keys:
{
"upstream_id": "0031U00000Qn2ZVQAZ",
"data": {
"FirstName": "Paul",
"LastName": "Atreides",
"Email": "paul@arrakis.org"
}
}
For deletes, you’ll send Sequin a list of upstream_id
s.
Note that the shape of the data
payload in creates and updates is the same shape that Sequin uses throughout the system for that collection. If ever in doubt, copy and paste the data
field from a record or event and use it as the starting point for your mutation.
Create mutation
For create mutations, the request body is a CreateMutationRequest
object with the following shape:
{
kind: "create";
sync_id: string;
collection_id: string;
data: PartialRecord[];
await_consumer_ids?: string[];
await_consumers_timeout?: number;
}
Parameters
The ID of the sync that the mutations should apply to.
The ID of the collection that the mutations should apply to.
A list of one or more PartialRecord
objects.
A list of one or more consumer IDs. See await consumers below.
The number of milliseconds to wait for consumers to finish processing a mutation. Defaults to 30000
(30 seconds). See await consumers below.
Update mutation
For update mutations, the request body is an UpdateMutationRequest
object with the following shape:
{
kind: "update";
sync_id: string;
collection_id: string;
data: PartialRecord[];
await_consumer_ids?: string[];
await_consumers_timeout?: number;
}
PATCH
in all update mutations.Parameters
The ID of the sync that the mutations should apply to.
The ID of the collection that the mutations should apply to.
A list of one or more PartialRecord
objects.
A list of one or more consumer IDs. See await consumers below.
The number of milliseconds to wait for consumers to finish processing a mutation. Defaults to 30000
(30 seconds). See await consumers below.
Delete mutation
For delete mutations, the request body is a DeleteMutationRequest
object with the following shape:
{
kind: "delete";
sync_id: string;
collection_id: string;
upstream_ids: string[];
await_consumer_ids?: string[];
await_consumers_timeout?: number;
}
Parameters
The ID of the sync that the mutations should apply to.
The ID of the collection that the mutations should apply to.
A list of one or more upstream IDs.
A list of one or more consumer IDs. See await consumers below.
The number of milliseconds to wait for consumers to finish processing a mutation. Defaults to 30000
(30 seconds). See await consumers below.
Response
If the mutation succeeds, Sequin will return a JSON object with a records
property containing each record:
{
"records": [
{
"sync_id": "70a313f8-7c94-43d4-8d0c-5659a52de5c4",
"collection_id" : "salesforce:task",
"upstream_id": "0018b000021BldZAAS",
"upstream_updated_at": "2024-11-10T18:39:00.070453Z",
"data": {
"activity_date": "2023-09-12",
"description" : "task description [ ... ] ",
// ...
},
"deleted": false,
// ...
}
]
}
If the mutation fails due to a validation error, Sequin will return a 400 Bad Request
response with an error message:
{
"error": "Error: Salesforce validation error: `Invalid email`",
"docs": [ ... ]
}
If the mutation fails due to the upstream API timing out, Sequin will return a 504 Gateway Timeout
response with an error message:
{
"error": "Error: Salesforce API timed out",
"docs": [ ... ]
}
Awaiting consumers
By default, Sequin applies mutations to the upstream API and to your streams, then returns a response. You can specify that you want your request to also block until the mutations have been applied to one or more consumers. This is useful if you need a read-after-write (or “read your writes”) workflow. For example, you might want to create a Salesforce Contact via the Mutation API, then re-render a view that pulls it from your database.
To await consumers, you can include the optional await_consumer_ids
property in your request. The value of await_consumer_ids
is a list of one or more consumer IDs. You can find the ID of a consumer in the Sequin console or via the Management API.
By default, Sequin will wait for consumers for up to 30 seconds. You can specify how long you want Sequin to wait by including an optional await_consumers_timeout
property in your request. The value of await_consumers_timeout
is the number of milliseconds to wait for consumers to finish processing the mutations, after the API mutation has succeeded.
If Sequin times out while waiting for consumers, it will return a 500
response with an error message:
{
"error": "Error: Timed out waiting for consumers: {consumer_id}",
"docs": [ ... ]
}
If the mutation was not idempotent (e.g. a create mutation), in this instance it is not safe to retry.
Examples
Create a single record:
curl -X POST \
https://api.sequin.io/v1/mutations/run \
-H 'content-type: application/json' \
-H 'authorization: Bearer {token}' \
-d '{
"kind": "create",
"sync_id": "my-sync-id",
"collection_id": "salesforce:contact",
"records": [
{
"data": {
"FirstName": "Paul",
"LastName": "Atreides",
"Email": "paul@arrakis.org"
}
}
]
}'
Create multiple records:
curl -X POST \
https://api.sequin.io/v1/mutations/run \
-H 'content-type: application/json' \
-H 'authorization: Bearer {token}' \
-d '{
"kind": "create",
"sync_id": "my-sync-id",
"collection_id": "salesforce:contact",
"records": [
{
"data": {
"FirstName": "Paul",
"LastName": "Atreides",
"Email": "paul@arrakis.org"
}
},
{
"data": {
"FirstName": "Duncan",
"LastName": "Idaho",
"Email": "duncan@arrakis.org"
}
}
]
}'
Update a single record:
curl -X POST \
https://api.sequin.io/v1/mutations/run \
-H 'content-type: application/json' \
-H 'authorization: Bearer {token}' \
-d '{
"kind": "update",
"sync_id": "my-sync-id",
"collection_id": "salesforce:contact",
"records": [
{
"upstream_id": "0031U00000Qn2ZVQAZ",
"data": {
"FirstName": "Paul",
"LastName": "Atreides",
"Email": "paul@arrakis.org"
}
}
]
}'
Update multiple records:
curl -X POST \
https://api.sequin.io/v1/mutations/run \
-H 'content-type: application/json' \
-H 'authorization: Bearer {token}' \
-d '{
"kind": "update",
"sync_id": "my-sync-id",
"collection_id": "salesforce:contact",
"records": [
{
"upstream_id": "0031U00000Qn2ZVQAZ",
"data": {
"FirstName": "Paul",
"LastName": "Atreides",
"Email": "paul@arrakis.org"
}
},
{
"upstream_id": "0031U00000Qn2ZVQBA",
"data": {
"FirstName": "Duncan",
"LastName": "Idaho",
"Email": "duncan@arrakis.org"
}
}
]
}'
Delete a single record:
curl -X POST \
https://api.sequin.io/v1/mutations/run \
-H 'content-type: application/json' \
-H 'authorization: Bearer {token}' \
-d '{
"kind": "delete",
"sync_id": "my-sync-id",
"collection_id": "salesforce:contact",
"upstream_ids": [
"0031U00000Qn2ZVQAZ"
]
}'
Delete multiple records:
curl -X POST \
https://api.sequin.io/v1/mutations/run \
-H 'content-type: application/json' \
-H 'authorization: Bearer {token}' \
-d '{
"kind": "delete",
"sync_id": "my-sync-id",
"collection_id": "salesforce:contact",
"upstream_ids": [
"0031U00000Qn2ZVQAZ",
"0031U00000Qn2ZVQBA"
]
}'
API proxy
The API proxy lets you make arbitrary requests to the upstream API. It’s useful for mutation requests that don’t map cleanly to a collection mutation. You can also use it for making one-off fetch requests against the upstream API.
When you use the API proxy, Sequin will authenticate your request and pace it to ensure that it doesn’t exceed rate limits.
Endpoints
For both proxy endpoints, the request body and headers are passed through to the upstream API. Sequin will augment the request with necessary authentication headers.
Proxy (sync)
[GET | POST | PUT | PATCH | DELETE] /v1/proxy/sync/:sync_id/:path
The parameters in the request:
sync_id
(required): The ID of the sync that corresponds to the request. This will determine where the request is proxied to.path
(required): The path of the request, according to the upstream API. For example,/contacts/839171
.
Proxy (credential)
[GET | POST | PUT | PATCH | DELETE] /v1/proxy/credential/:credential_id/:path
The parameters in the request:
credential_id
(required): The ID of the credential that corresponds to the request. This will determine where the request is proxied to.path
(required): The path of the request, according to the upstream API. For example,/contacts/839171
.
Examples
POST
a change to the API:
curl -X POST \
https://api.sequin.io/v1/proxy/sync/sync-67b58087/v1/payment_intents/pm_1234/cancel \
-H 'authorization: Bearer {token}' \
-H 'content-type: application/json' \
-d '{
"cancellation_reason": "requested_by_customer"
}'
curl -X POST \
https://api.sequin.io/v1/proxy/credential/credential-8391jIli/v1/payment_intents/pm_1234/cancel \
-H 'authorization: Bearer {token}' \
-H 'content-type: application/json' \
-d '{
"cancellation_reason": "requested_by_customer"
}'
PUT
a change to the API:
curl -X PUT \
https://api.sequin.io/v1/proxy/sync/sync-67b58087/crm/v4/objects/12345/associations/company/67891 \
-H 'authorization: Bearer {token}' \
-H 'content-type: application/json' \
-d '{
"associationCategory": "USER_DEFINED",
"associationTypeId": 36
}'
curl -X PUT \
https://api.sequin.io/v1/proxy/credential/credential-8391jIli/crm/v4/objects/12345/associations/company/67891 \
-H 'authorization: Bearer {token}' \
-H 'content-type: application/json' \
-d '{
"associationCategory": "USER_DEFINED",
"associationTypeId": 36
}'
GET
a record from the API:
curl -X GET \
-H 'authorization: Bearer {token}' \
https://api.sequin.io/v1/proxy/sync/sync-67b58087/contacts/12345
curl -X GET \
-H 'authorization: Bearer {token}' \
https://api.sequin.io/v1/proxy/credential/credential-8391jIli/contacts/12345
Was this page helpful?