Change items
data.collection.mutate@1
Adds, changes, archives or deletes one row in a table this key can change. A change to an existing row names the revision you read it at, so a change made since then is never overwritten. It needs a key with Act.
Add a row
Send POST /invocations with the target this operation's catalogue entry gives: replace YOUR_FEATURE_ID with its featureId, and YOUR_TABLE_REF with a table's resourceRef from List data tables. The field ids are the table's own (fields[].id).
# A new operationId for each new request; the same one to retry it.
curl https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations \
-H "Authorization: Bearer gl_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"target": {
"featureId": "YOUR_FEATURE_ID",
"export": "mutateCollection",
"contractRef": "data.collection.mutate@1"
},
"operationId": "add-quote-request-1",
"input": {
"resourceRef": "YOUR_TABLE_REF",
"mutation": {
"kind": "create",
"values": {
"f_name": "Jordan Example",
"f_email": "jordan@example.com",
"f_details": "A two-tier cake for 40 guests"
}
}
}
}'
// A new operationId for each new request; the same one to retry it.
const response = await fetch(
"https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
{
method: "POST",
headers: {
Authorization: "Bearer gl_YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"target": {
"featureId": "YOUR_FEATURE_ID",
"export": "mutateCollection",
"contractRef": "data.collection.mutate@1"
},
"operationId": "add-quote-request-1",
"input": {
"resourceRef": "YOUR_TABLE_REF",
"mutation": {
"kind": "create",
"values": {
"f_name": "Jordan Example",
"f_email": "jordan@example.com",
"f_details": "A two-tier cake for 40 guests"
}
}
}
}),
},
);
const receipt = await response.json();
console.log(response.status, receipt);
import requests
# A new operationId for each new request; the same one to retry it.
response = requests.post(
"https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
headers={"Authorization": "Bearer gl_YOUR_API_KEY"},
json={
"target": {
"featureId": "YOUR_FEATURE_ID",
"export": "mutateCollection",
"contractRef": "data.collection.mutate@1",
},
"operationId": "add-quote-request-1",
"input": {
"resourceRef": "YOUR_TABLE_REF",
"mutation": {
"kind": "create",
"values": {
"f_name": "Jordan Example",
"f_email": "jordan@example.com",
"f_details": "A two-tier cake for 40 guests",
},
},
},
},
timeout=30,
)
print(response.status_code, response.json())
Change a row
Copy row from the row's recordRef and expectedRevision from its revision, as Read a list or the last change's answer gives them. Only the fields in values change.
# A new operationId for each new request; the same one to retry it.
curl https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations \
-H "Authorization: Bearer gl_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"target": {
"featureId": "YOUR_FEATURE_ID",
"export": "mutateCollection",
"contractRef": "data.collection.mutate@1"
},
"operationId": "change-quote-request-1",
"input": {
"resourceRef": "YOUR_TABLE_REF",
"mutation": {
"kind": "patch",
"row": {
"businessProfileId": "YOUR_BUSINESS_ID",
"featureId": "YOUR_ROW_FEATURE_ID",
"collectionId": "YOUR_ROW_COLLECTION_ID",
"id": "YOUR_ROW_ID"
},
"expectedRevision": 1,
"values": {
"f_phone": "555-0100"
}
}
}
}'
// A new operationId for each new request; the same one to retry it.
const response = await fetch(
"https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
{
method: "POST",
headers: {
Authorization: "Bearer gl_YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"target": {
"featureId": "YOUR_FEATURE_ID",
"export": "mutateCollection",
"contractRef": "data.collection.mutate@1"
},
"operationId": "change-quote-request-1",
"input": {
"resourceRef": "YOUR_TABLE_REF",
"mutation": {
"kind": "patch",
"row": {
"businessProfileId": "YOUR_BUSINESS_ID",
"featureId": "YOUR_ROW_FEATURE_ID",
"collectionId": "YOUR_ROW_COLLECTION_ID",
"id": "YOUR_ROW_ID"
},
"expectedRevision": 1,
"values": {
"f_phone": "555-0100"
}
}
}
}),
},
);
const receipt = await response.json();
console.log(response.status, receipt);
import requests
# A new operationId for each new request; the same one to retry it.
response = requests.post(
"https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
headers={"Authorization": "Bearer gl_YOUR_API_KEY"},
json={
"target": {
"featureId": "YOUR_FEATURE_ID",
"export": "mutateCollection",
"contractRef": "data.collection.mutate@1",
},
"operationId": "change-quote-request-1",
"input": {
"resourceRef": "YOUR_TABLE_REF",
"mutation": {
"kind": "patch",
"row": {
"businessProfileId": "YOUR_BUSINESS_ID",
"featureId": "YOUR_ROW_FEATURE_ID",
"collectionId": "YOUR_ROW_COLLECTION_ID",
"id": "YOUR_ROW_ID",
},
"expectedRevision": 1,
"values": {
"f_phone": "555-0100",
},
},
},
},
timeout=30,
)
print(response.status_code, response.json())
Parameters
What goes in input:
| Name | Type | Required | Description |
|---|---|---|---|
resourceRef |
string | Yes | The table to change: its resourceRef from List data tables. |
mutation |
object | Yes | The one change to make. |
mutation.kind |
one of create, patch, archive, unarchive, delete, restore |
Yes | What to do: create adds a row; patch changes some of a row's values; archive and unarchive put a row away and bring it back; delete moves it to Trash, where it can be restored for 30 days; restore brings it back from Trash. |
mutation.values |
object | Sometimes | Field values keyed by field id (f_…). Required for create and patch; unarchive may correct values as it restores. patch changes only the fields you send. |
mutation.idempotencyKey |
string | No | create only, 1 to 128 characters: a second create with the same key in this table answers with the row the first one made instead of adding another. A table with an identity field (idempotencyFieldId in List data tables) uses that field's value as the key. |
mutation.row |
object | Sometimes | The row to change, as its recordRef from Read a list. Required for every kind but create. |
mutation.row.businessProfileId |
string | Yes | Your business's id. |
mutation.row.featureId |
string | Yes | The featureId of the row's recordRef. |
mutation.row.collectionId |
string | Yes | The collectionId of the row's recordRef. |
mutation.row.id |
string | Yes | The row's id. |
mutation.expectedRevision |
integer | Sometimes | The row's revision when you read it. Required for every kind but create: if the row has changed since, nothing is changed and the answer is a conflict. |
Response
A call that worked answers 200 with an applied receipt; its output holds these fields, among others. GET /catalog/data.collection.mutate@1 answers the complete shape as JSON Schema.
| Name | Type | Description |
|---|---|---|
row |
object | The row the change made or changed, as row for the next change. |
row.id |
string | The row's id. |
revision |
integer | The row's new revision: send it as expectedRevision with the next change. |
{
"status": "applied",
"operationId": "add-quote-request-1",
"output": {
"row": {
"businessProfileId": "YOUR_BUSINESS_ID",
"featureId": "juniper-cakes.data",
"collectionId": "juniper-cakes.quote-requests",
"id": "0b6f3c2a-5d1e-4f7a-9c8b-2e4d6f8a1c3e"
},
"revision": 1
}
}
Errors
Besides the answers every request can get (Errors), its receipt can say:
| Status | HTTP | What it means |
|---|---|---|
pending |
202 | Accepted and still running. Look it up with GET /operations/{operationId}. |
uncertain |
202 | GrowLocal can't yet tell whether it took effect. Look it up before trying again. |
requirements |
409 | Something must happen first; the receipt lists what. |
conflict |
409 | The row changed since you read it, or this operationId was used with a different body. |
rejected |
400, or 403 when it's a matter of access | Not done. diagnostics says why: each has a code, a path into what you sent and a message. |
The codes in diagnostics you're most likely to see:
| Code | Status | What it means |
|---|---|---|
DATA.REVISION_CONFLICT |
conflict |
The row is at another revision than expectedRevision: someone changed it since you read it. Read it again. |
DATA.OPERATION_REPLAY_MISMATCH |
conflict |
This operationId was already used with a different body. Use a new one. |
DATA.FIELD_UNKNOWN |
rejected |
The table has no field with that id. |
DATA.FIELD_MANAGED |
rejected |
That field is written only by GrowLocal's own step for it, such as a status. |
DATA.RESOURCE_NOT_FOUND |
rejected |
No such table here for this key. |