Make posts from a recipe
social.posts.generate@1
Starts a chosen content setup that writes one draft post for each account you choose. The call answers as soon as the work is accepted; the drafts follow, and nothing is approved, dated or published. It needs a key with Write social.
Write a post for an account
Replace YOUR_RECIPE_REF with a content setup's reference and YOUR_ACCOUNT_ID with an account's id. The answers are the setup's own questions.
# 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": "generatePosts",
"contractRef": "social.posts.generate@1"
},
"operationId": "generate-posts-1",
"input": {
"recipeRef": "YOUR_RECIPE_REF",
"answers": {
"topic": "Lemon drizzle cake"
},
"accountRefs": [
{
"businessProfileId": "YOUR_BUSINESS_ID",
"featureId": "juniper-cakes.social",
"collectionId": "juniper-cakes.accounts",
"id": "YOUR_ACCOUNT_ID"
}
]
}
}'
// 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": "generatePosts",
"contractRef": "social.posts.generate@1"
},
"operationId": "generate-posts-1",
"input": {
"recipeRef": "YOUR_RECIPE_REF",
"answers": {
"topic": "Lemon drizzle cake"
},
"accountRefs": [
{
"businessProfileId": "YOUR_BUSINESS_ID",
"featureId": "juniper-cakes.social",
"collectionId": "juniper-cakes.accounts",
"id": "YOUR_ACCOUNT_ID"
}
]
}
}),
},
);
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": "generatePosts",
"contractRef": "social.posts.generate@1",
},
"operationId": "generate-posts-1",
"input": {
"recipeRef": "YOUR_RECIPE_REF",
"answers": {
"topic": "Lemon drizzle cake",
},
"accountRefs": [
{
"businessProfileId": "YOUR_BUSINESS_ID",
"featureId": "juniper-cakes.social",
"collectionId": "juniper-cakes.accounts",
"id": "YOUR_ACCOUNT_ID",
},
],
},
},
timeout=30,
)
print(response.status_code, response.json())
Parameters
What goes in input:
| Name | Type | Required | Description |
|---|---|---|---|
recipeRef |
string | Yes | The content setup to use, by its reference. |
answers |
object | Yes | Your answers to that setup's questions, by question. |
accountRefs |
array of object | Yes | The accounts to write for, 1 to 10, one post version each; one listed twice is refused. |
accountRefs[].businessProfileId |
string | Yes | Your business's id. |
accountRefs[].featureId |
string | Yes | The featureId of the account's row. |
accountRefs[].collectionId |
string | Yes | The collectionId of the account's row. |
accountRefs[].id |
string | Yes | The account's id. |
Response
A call that worked answers 200 with an applied receipt; its output holds these fields, among others. GET /catalog/social.posts.generate@1 answers the complete shape as JSON Schema.
| Name | Type | Description |
|---|---|---|
runRef |
string | The run that is writing the drafts: follow it with Automation run inspector. |
featureId |
string | The feature the run belongs to. |
accountOutcomes |
array of object | One entry per account, pending at first. |
accountOutcomes[].accountRef |
object | The account. |
accountOutcomes[].sourceItemKey |
string or null | The key of the result it is made from, or null. |
accountOutcomes[].status |
one of pending, saved, not-saved, cancelled, skipped |
pending, saved, not-saved, cancelled or skipped. |
accountOutcomes[].editionRef |
object or null | The saved draft, or null. |
accountOutcomes[].editionRevision |
integer or null | The draft's revision, or null. |
accountOutcomes[].reason |
object or null | Why nothing was saved, or null. |
{
"status": "applied",
"operationId": "generate-posts-1",
"output": {
"runRef": "11111111-2222-4333-8444-555555555555",
"featureId": "juniper-cakes.automations",
"accountOutcomes": [
{
"accountRef": {
"businessProfileId": "YOUR_BUSINESS_ID",
"featureId": "juniper-cakes.social",
"collectionId": "juniper-cakes.accounts",
"id": "YOUR_ACCOUNT_ID"
},
"sourceItemKey": null,
"status": "pending",
"editionRef": null,
"editionRevision": null,
"reason": null
}
]
}
}
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 |
|---|---|---|
SOCIAL.RECIPE_UNAVAILABLE |
rejected |
recipeRef is not a content setup this business can use. |
SOCIAL.ACCOUNT_DUPLICATE |
rejected |
An account is listed twice. |
SOCIAL.PLATFORM_UNSUPPORTED |
rejected |
An account's platform cannot be published to. |
DATA.ROW_NOT_FOUND |
rejected |
No such account here for this key. |