Campaigns
- get/v1/campaigns
- post/v1/campaigns
- get/v1/campaigns/{id}
- patch/v1/campaigns/{id}
- put/v1/campaigns/{id}/status
- put/v1/campaigns/{id}/personas
- get/v1/campaigns/{id}/results
- get/v1/campaigns/{id}/deliverables
- put/v1/campaigns/{id}/posts/{postId}
- del/v1/campaigns/{id}/posts/{postId}
- get/v1/personas
- post/v1/personas
- patch/v1/personas/{id}
- post/v1/personas/{id}/archive
- get/v1/objectives
- post/v1/objectives
- patch/v1/objectives/{id}
- post/v1/objectives/{id}/archive
List campaigns
get/v1/campaigns
List the workspace's campaigns with post counts per status and this month's cadence progress. Filter with a comma-separated `status`. Needs campaigns:view; client-visibility members receive the client view without internal notes.
Query parameters
statusstring
Response 200
Campaigns
dataarray of objectrequiredChild attributes
idstringrequiredworkspaceIdstringrequiredaudiencestringrequiredOne of
teamclientnamestringrequiredobjectiveIdstringrequirednullablecreativeDirectionstringrequirednullablestatusstringrequiredOne of
draftactivecompletedarchivedstartAtstring (date-time)requirednullableendAtstring (date-time)requirednullablecolorstringrequirednullableongoingbooleanrequiredpersonaIdsarray of stringrequiredpostCountsmap of numberrequiredcoverImageUrlstringrequirednullableinternalNotesstringnullablemonthlyPostTargetintegernullableprogressCountintegernullablecreatedBystringnullablecreatedAtstring (date-time)updatedAtstring (date-time)
Errors
- 400
- Invalid status filter
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
curl "https://api.posty.social/v1/campaigns" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"data": [
{
"id": "string",
"workspaceId": "string",
"audience": "team",
"name": "string",
"objectiveId": "string",
"creativeDirection": "string",
"status": "draft",
"startAt": "2026-01-15T09:30:00.000Z",
"endAt": "2026-01-15T09:30:00.000Z",
"color": "string",
"ongoing": true,
"personaIds": [
"string"
],
"postCounts": {
"key": 1
},
"coverImageUrl": "string",
"internalNotes": "string",
"monthlyPostTarget": 1,
"progressCount": 1,
"createdBy": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}
]
}Create campaign
post/v1/campaigns
Create a campaign: a bounded launch (startAt and endAt) or an ongoing theme (no dates plus monthlyPostTarget). Needs campaigns:create and counts against the plan's campaign limit (402 when reached).
Request body
namestringrequiredMin length 1 · Max length 200
objectiveIdstringnullableMin length 1
personaIdsarray of stringDefault [] · Max items 50
creativeDirectionstringnullableMax length 5000
internalNotesstringnullableMax length 5000
statusstringOne of
draftactivecompletedarchivedDefault "draft"
startAtstring (date-time)nullableendAtstring (date-time)nullablemonthlyPostTargetintegernullableMin 1 · Max 1000
colorstringnullableMax length 32
Response 201
Campaign created
idstringrequiredworkspaceIdstringrequiredaudiencestringrequiredOne of
teamclientnamestringrequiredobjectiveIdstringrequirednullablecreativeDirectionstringrequirednullablestatusstringrequiredOne of
draftactivecompletedarchivedstartAtstring (date-time)requirednullableendAtstring (date-time)requirednullablecolorstringrequirednullableongoingbooleanrequiredpersonaIdsarray of stringrequiredpostCountsmap of numberrequiredcoverImageUrlstringrequirednullableinternalNotesstringnullablemonthlyPostTargetintegernullableprogressCountintegernullablecreatedBystringnullablecreatedAtstring (date-time)updatedAtstring (date-time)
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 402
- Campaign limit reached
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X POST "https://api.posty.social/v1/campaigns" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"objectiveId": "string",
"personaIds": [],
"creativeDirection": "string",
"internalNotes": "string",
"status": "draft",
"startAt": "2026-01-15T09:30:00.000Z",
"endAt": "2026-01-15T09:30:00.000Z",
"monthlyPostTarget": 1,
"color": "string"
}'{
"id": "string",
"workspaceId": "string",
"audience": "team",
"name": "string",
"objectiveId": "string",
"creativeDirection": "string",
"status": "draft",
"startAt": "2026-01-15T09:30:00.000Z",
"endAt": "2026-01-15T09:30:00.000Z",
"color": "string",
"ongoing": true,
"personaIds": [
"string"
],
"postCounts": {
"key": 1
},
"coverImageUrl": "string",
"internalNotes": "string",
"monthlyPostTarget": 1,
"progressCount": 1,
"createdBy": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}Get campaign
get/v1/campaigns/{id}
Get one campaign's brief: objective, personas, creative direction, dates or monthly target, and post counts. Needs campaigns:view; client-visibility members receive the client view without internal notes.
Path parameters
idstringrequired
Response 200
Campaign
idstringrequiredworkspaceIdstringrequiredaudiencestringrequiredOne of
teamclientnamestringrequiredobjectiveIdstringrequirednullablecreativeDirectionstringrequirednullablestatusstringrequiredOne of
draftactivecompletedarchivedstartAtstring (date-time)requirednullableendAtstring (date-time)requirednullablecolorstringrequirednullableongoingbooleanrequiredpersonaIdsarray of stringrequiredpostCountsmap of numberrequiredcoverImageUrlstringrequirednullableinternalNotesstringnullablemonthlyPostTargetintegernullableprogressCountintegernullablecreatedBystringnullablecreatedAtstring (date-time)updatedAtstring (date-time)
Errors
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
curl "https://api.posty.social/v1/campaigns/$ID" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"id": "string",
"workspaceId": "string",
"audience": "team",
"name": "string",
"objectiveId": "string",
"creativeDirection": "string",
"status": "draft",
"startAt": "2026-01-15T09:30:00.000Z",
"endAt": "2026-01-15T09:30:00.000Z",
"color": "string",
"ongoing": true,
"personaIds": [
"string"
],
"postCounts": {
"key": 1
},
"coverImageUrl": "string",
"internalNotes": "string",
"monthlyPostTarget": 1,
"progressCount": 1,
"createdBy": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}Update campaign
patch/v1/campaigns/{id}
Edit a campaign's brief. Omitted fields are left alone and null clears a field. Needs campaigns:update. Use set_campaign_status for status and set_campaign_personas for target personas.
Path parameters
idstringrequired
Request body
namestringMin length 1 · Max length 200
objectiveIdstringnullableMin length 1
creativeDirectionstringnullableMax length 5000
internalNotesstringnullableMax length 5000
startAtstring (date-time)nullableendAtstring (date-time)nullablemonthlyPostTargetintegernullableMin 1 · Max 1000
colorstringnullableMax length 32
Response 200
Campaign updated
idstringrequiredworkspaceIdstringrequiredaudiencestringrequiredOne of
teamclientnamestringrequiredobjectiveIdstringrequirednullablecreativeDirectionstringrequirednullablestatusstringrequiredOne of
draftactivecompletedarchivedstartAtstring (date-time)requirednullableendAtstring (date-time)requirednullablecolorstringrequirednullableongoingbooleanrequiredpersonaIdsarray of stringrequiredpostCountsmap of numberrequiredcoverImageUrlstringrequirednullableinternalNotesstringnullablemonthlyPostTargetintegernullableprogressCountintegernullablecreatedBystringnullablecreatedAtstring (date-time)updatedAtstring (date-time)
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X PATCH "https://api.posty.social/v1/campaigns/$ID" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"objectiveId": "string",
"creativeDirection": "string",
"internalNotes": "string",
"startAt": "2026-01-15T09:30:00.000Z",
"endAt": "2026-01-15T09:30:00.000Z",
"monthlyPostTarget": 1,
"color": "string"
}'{
"id": "string",
"workspaceId": "string",
"audience": "team",
"name": "string",
"objectiveId": "string",
"creativeDirection": "string",
"status": "draft",
"startAt": "2026-01-15T09:30:00.000Z",
"endAt": "2026-01-15T09:30:00.000Z",
"color": "string",
"ongoing": true,
"personaIds": [
"string"
],
"postCounts": {
"key": 1
},
"coverImageUrl": "string",
"internalNotes": "string",
"monthlyPostTarget": 1,
"progressCount": 1,
"createdBy": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}Set campaign status
put/v1/campaigns/{id}/status
Move a campaign between draft, active, completed and archived. Needs campaigns:update, and campaigns:archive to archive. An archived campaign accepts no new deliverables.
Path parameters
idstringrequired
Request body
statusstringrequiredOne of
draftactivecompletedarchived
Response 200
Campaign status set
idstringrequiredworkspaceIdstringrequiredaudiencestringrequiredOne of
teamclientnamestringrequiredobjectiveIdstringrequirednullablecreativeDirectionstringrequirednullablestatusstringrequiredOne of
draftactivecompletedarchivedstartAtstring (date-time)requirednullableendAtstring (date-time)requirednullablecolorstringrequirednullableongoingbooleanrequiredpersonaIdsarray of stringrequiredpostCountsmap of numberrequiredcoverImageUrlstringrequirednullableinternalNotesstringnullablemonthlyPostTargetintegernullableprogressCountintegernullablecreatedBystringnullablecreatedAtstring (date-time)updatedAtstring (date-time)
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X PUT "https://api.posty.social/v1/campaigns/$ID/status" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "draft"
}'{
"id": "string",
"workspaceId": "string",
"audience": "team",
"name": "string",
"objectiveId": "string",
"creativeDirection": "string",
"status": "draft",
"startAt": "2026-01-15T09:30:00.000Z",
"endAt": "2026-01-15T09:30:00.000Z",
"color": "string",
"ongoing": true,
"personaIds": [
"string"
],
"postCounts": {
"key": 1
},
"coverImageUrl": "string",
"internalNotes": "string",
"monthlyPostTarget": 1,
"progressCount": 1,
"createdBy": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}Set campaign personas
put/v1/campaigns/{id}/personas
Replace the set of personas a campaign targets with personaIds (find or create them with get_or_create_persona). Needs campaigns:update.
Path parameters
idstringrequired
Request body
personaIdsarray of stringrequiredMax items 50
Response 200
Campaign personas set
campaignIdstringrequiredpersonaIdsarray of stringrequired
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X PUT "https://api.posty.social/v1/campaigns/$ID/personas" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"personaIds": [
"string"
]
}'{
"campaignId": "string",
"personaIds": [
"string"
]
}Get campaign results
get/v1/campaigns/{id}/results
Campaign performance over the last `days` (default 30, clamped to the plan's analytics retention): comparative findings plus totals, per-post and per-persona reach. available is false when the plan keeps no analytics. Needs campaigns:view; client-visibility members get headline numbers and findings only.
Path parameters
idstringrequired
Query parameters
daysintegerDefault 30 · Min 1 · Max 365
Response 200
Campaign results
campaignIdstringrequiredaudiencestringrequiredOne of
teamclientavailablebooleanrequiredfindingsarray of stringrequiredwindowDaysintegertotalsobjectnullableChild attributes
reachnumberrequiredimpressionsnumberrequiredlikesnumberrequiredcommentsnumberrequiredsharesnumberrequiredsavesnumberrequiredclicksnumberrequiredpostCountnumberrequired
postsarray of objectChild attributes
postIdstringrequiredbodystringrequiredpersonaIdstringrequirednullablereachnumberrequiredengagementsnumberrequired
personasarray of objectChild attributes
personaIdstringrequirednamestringrequiredreachnumberrequiredengagementsnumberrequiredpostCountnumberrequired
reachnumberimpressionsnumberengagementsnumberpostCountnumber
Errors
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
curl "https://api.posty.social/v1/campaigns/$ID/results" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"campaignId": "string",
"audience": "team",
"available": true,
"findings": [
"string"
],
"windowDays": 1,
"totals": {
"reach": 1,
"impressions": 1,
"likes": 1,
"comments": 1,
"shares": 1,
"saves": 1,
"clicks": 1,
"postCount": 1
},
"posts": [
{
"postId": "string",
"body": "string",
"personaId": "string",
"reach": 1,
"engagements": 1
}
],
"personas": [
{
"personaId": "string",
"name": "string",
"reach": 1,
"engagements": 1,
"postCount": 1
}
],
"reach": 1,
"impressions": 1,
"engagements": 1,
"postCount": 1
}List campaign deliverables
get/v1/campaigns/{id}/deliverables
List the posts filed under a campaign with their summary text, status, schedule, persona, platforms and a signed thumbnail URL. Needs posts:view; post statuses the caller may not see are left out.
Path parameters
idstringrequired
Query parameters
limitintegerDefault 200 · Min 1 · Max 500
Response 200
Campaign deliverables
dataarray of objectrequiredChild attributes
idstringrequiredbodystringrequiredstatusstringrequiredOne of
draftpending_approvalpending_client_approvalapprovedscheduleddeliveredpartially_delivereddelivery_failedscheduledAtstring (date-time)requirednullableupdatedAtstring (date-time)requiredpersonaIdstringrequirednullablechannelIdsarray of stringrequiredplatformsarray of stringrequiredOne of
blueskydiscordfacebookinstagramlinkedinpinterestthreadstiktokwordpressyoutubethumbnailstringrequirednullable
Errors
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
curl "https://api.posty.social/v1/campaigns/$ID/deliverables" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"data": [
{
"id": "string",
"body": "string",
"status": "draft",
"scheduledAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"personaId": "string",
"channelIds": [
"string"
],
"platforms": [
"bluesky"
],
"thumbnail": "string"
}
]
}Add post to campaign
put/v1/campaigns/{id}/posts/{postId}
File an existing post under this campaign as a deliverable, moving it out of any other campaign, and optionally set the persona it speaks to. Needs posts:update; the post must still be editable and the campaign not archived.
Path parameters
idstringrequiredpostIdstringrequired
Request body
personaIdstringnullableMin length 1
Response 200
Post filed
postIdstringrequiredcampaignIdstringrequirednullablepersonaIdstringrequirednullablestatusstringrequiredOne of
draftpending_approvalpending_client_approvalapprovedscheduleddeliveredpartially_delivereddelivery_failed
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X PUT "https://api.posty.social/v1/campaigns/$ID/posts/$POST_ID" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"personaId": "string"
}'{
"postId": "string",
"campaignId": "string",
"personaId": "string",
"status": "draft"
}Remove post from campaign
del/v1/campaigns/{id}/posts/{postId}
Detach a post from this campaign and clear its persona. The post itself is kept. Needs posts:update; answers 404 when the post is not in this campaign.
Path parameters
idstringrequiredpostIdstringrequired
Response 204
Post detached
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X DELETE "https://api.posty.social/v1/campaigns/$ID/posts/$POST_ID" \
-H "Authorization: Bearer $POSTY_API_KEY"No contentSearch personas
get/v1/personas
Search the workspace's personas (target audiences) by name, case-insensitively. Archived personas are excluded unless includeArchived is true. Needs campaigns:view.
Query parameters
querystringMax length 200
includeArchivedstringOne of
truefalselimitintegerDefault 20 · Min 1 · Max 50
Response 200
Personas
dataarray of objectrequiredChild attributes
idstringrequiredworkspaceIdstringrequirednamestringrequireddescriptionstringrequirednullablecolorstringrequirednullabletemplateKeystringrequirednullablearchivedAtstring (date-time)requirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)required
Errors
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
curl "https://api.posty.social/v1/personas" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"data": [
{
"id": "string",
"workspaceId": "string",
"name": "string",
"description": "string",
"color": "string",
"templateKey": "string",
"archivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}
]
}Get or create persona
post/v1/personas
Return the workspace persona with this name (matched case-insensitively), creating it when none exists. created tells which happened; an existing persona's fields are not changed. Needs campaigns:create.
Request body
namestringrequiredMin length 1 · Max length 200
descriptionstringnullableMax length 5000
colorstringnullableMax length 32
templateKeystringnullableMax length 100
Response 200
Existing persona
personaobjectrequiredChild attributes
idstringrequiredworkspaceIdstringrequirednamestringrequireddescriptionstringrequirednullablecolorstringrequirednullabletemplateKeystringrequirednullablearchivedAtstring (date-time)requirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)required
createdbooleanrequired
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X POST "https://api.posty.social/v1/personas" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"description": "string",
"color": "string",
"templateKey": "string"
}'{
"persona": {
"id": "string",
"workspaceId": "string",
"name": "string",
"description": "string",
"color": "string",
"templateKey": "string",
"archivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"created": true
}Update persona
patch/v1/personas/{id}
Rename a persona or change its description or color. Needs campaigns:update.
Path parameters
idstringrequired
Request body
namestringMin length 1 · Max length 200
descriptionstringnullableMax length 5000
colorstringnullableMax length 32
Response 200
Persona updated
idstringrequiredworkspaceIdstringrequirednamestringrequireddescriptionstringrequirednullablecolorstringrequirednullabletemplateKeystringrequirednullablearchivedAtstring (date-time)requirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)required
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X PATCH "https://api.posty.social/v1/personas/$ID" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"description": "string",
"color": "string"
}'{
"id": "string",
"workspaceId": "string",
"name": "string",
"description": "string",
"color": "string",
"templateKey": "string",
"archivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}Archive persona
post/v1/personas/{id}/archive
Archive a persona so pickers stop offering it (archived: false restores it). Existing campaign and post links are kept. Needs campaigns:archive.
Path parameters
idstringrequired
Request body
archivedbooleanDefault true
Response 200
Persona archived or restored
idstringrequiredworkspaceIdstringrequirednamestringrequireddescriptionstringrequirednullablecolorstringrequirednullabletemplateKeystringrequirednullablearchivedAtstring (date-time)requirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)required
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X POST "https://api.posty.social/v1/personas/$ID/archive" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"archived": true
}'{
"id": "string",
"workspaceId": "string",
"name": "string",
"description": "string",
"color": "string",
"templateKey": "string",
"archivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}Search objectives
get/v1/objectives
Search the workspace's campaign objectives by name, case-insensitively. Archived objectives are excluded unless includeArchived is true. Needs campaigns:view.
Query parameters
querystringMax length 200
includeArchivedstringOne of
truefalselimitintegerDefault 20 · Min 1 · Max 50
Response 200
Objectives
dataarray of objectrequiredChild attributes
idstringrequiredworkspaceIdstringrequirednamestringrequireddescriptionstringrequirednullabletargetMetricKeystringrequirednullabletargetValueintegerrequirednullabletemplateKeystringrequirednullablearchivedAtstring (date-time)requirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)required
Errors
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
curl "https://api.posty.social/v1/objectives" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"data": [
{
"id": "string",
"workspaceId": "string",
"name": "string",
"description": "string",
"targetMetricKey": "string",
"targetValue": 1,
"templateKey": "string",
"archivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}
]
}Get or create objective
post/v1/objectives
Return the workspace objective with this name (matched case-insensitively), creating it when none exists. created tells which happened; an existing objective's fields are not changed. Needs campaigns:create.
Request body
namestringrequiredMin length 1 · Max length 200
descriptionstringnullableMax length 5000
targetMetricKeystringnullableMax length 100
targetValueintegernullableMin 0
templateKeystringnullableMax length 100
Response 200
Existing objective
objectiveobjectrequiredChild attributes
idstringrequiredworkspaceIdstringrequirednamestringrequireddescriptionstringrequirednullabletargetMetricKeystringrequirednullabletargetValueintegerrequirednullabletemplateKeystringrequirednullablearchivedAtstring (date-time)requirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)required
createdbooleanrequired
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X POST "https://api.posty.social/v1/objectives" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"description": "string",
"targetMetricKey": "string",
"targetValue": 1,
"templateKey": "string"
}'{
"objective": {
"id": "string",
"workspaceId": "string",
"name": "string",
"description": "string",
"targetMetricKey": "string",
"targetValue": 1,
"templateKey": "string",
"archivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"created": true
}Update objective
patch/v1/objectives/{id}
Rename an objective or change its description, target metric or target value. Needs campaigns:update.
Path parameters
idstringrequired
Request body
namestringMin length 1 · Max length 200
descriptionstringnullableMax length 5000
targetMetricKeystringnullableMax length 100
targetValueintegernullableMin 0
Response 200
Objective updated
idstringrequiredworkspaceIdstringrequirednamestringrequireddescriptionstringrequirednullabletargetMetricKeystringrequirednullabletargetValueintegerrequirednullabletemplateKeystringrequirednullablearchivedAtstring (date-time)requirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)required
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X PATCH "https://api.posty.social/v1/objectives/$ID" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"description": "string",
"targetMetricKey": "string",
"targetValue": 1
}'{
"id": "string",
"workspaceId": "string",
"name": "string",
"description": "string",
"targetMetricKey": "string",
"targetValue": 1,
"templateKey": "string",
"archivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}Archive objective
post/v1/objectives/{id}/archive
Archive an objective so pickers stop offering it (archived: false restores it). Campaigns pointing at it are kept. Needs campaigns:archive.
Path parameters
idstringrequired
Request body
archivedbooleanDefault true
Response 200
Objective archived or restored
idstringrequiredworkspaceIdstringrequirednamestringrequireddescriptionstringrequirednullabletargetMetricKeystringrequirednullabletargetValueintegerrequirednullabletemplateKeystringrequirednullablearchivedAtstring (date-time)requirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)required
Errors
- 400
- Invalid request
- 401
- Unauthenticated
- 403
- Missing scope, or campaigns are disabled
- 404
- Not found
- 409
- Conflicting change
curl -X POST "https://api.posty.social/v1/objectives/$ID/archive" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"archived": true
}'{
"id": "string",
"workspaceId": "string",
"name": "string",
"description": "string",
"targetMetricKey": "string",
"targetValue": 1,
"templateKey": "string",
"archivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}