Templates
6 endpoints in this family.
List message templates
GET/api/v1/templates
Returns the templates of the workspace with their approval state: approved ones can be sent outside the 24-hour window, the others cannot yet.
A template is identified at Meta by its name AND its language — the same name in two languages is two templates.
Response
The templates, with their status, category, body and placeholders.
data.itemsTemplate[]The templates, recently changed first.
data.summaryobjectCounts:
total,draft,submitted,approved,rejected.
curl https://coplace.io/api/v1/templates \ -H "Authorization: Bearer $COPLACE_KEY"{ "data": { "items": [ {} ], "summary": {} }}Draft a template
POST/api/v1/templates
Key role admin or above
Writes a template on the Coplace side. Nothing is sent to Meta yet — drafting and submitting are two steps on purpose, because submission reserves the name at Meta and cannot be undone. Submit with POST /templates/{id}/submit.
Body
namestringrequiredLowercase letters, digits and underscores. Reserved at Meta on submission.
languagestringrequiredLanguage tag, for example
froren_US.categorystringrequiredWhat Meta charges it as.
UTILITYMARKETINGAUTHENTICATIONbodystringrequiredThe text, with
{{1}}style placeholders.headerstringAn optional one-line header.
footerstringAn optional footer.
buttonsobject[]Up to three buttons: url, quick reply, or copy code.
Response
The template as drafted, not yet submitted.
data.templateTemplate
curl -X POST https://coplace.io/api/v1/templates \ -H "Authorization: Bearer $COPLACE_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "…", "language": "fr", "category": "UTILITY", "body": "…" }'{ "data": { "template": { "id": "…", "name": "…", "language": "…", "category": "UTILITY", "status": "draft", "body": "…", "rejectionReason": "…", "createdAt": "…", "updatedAt": "…" } }}Get one template
GET/api/v1/templates/{id}
Returns the template with its current approval state and full definition.
Path parameters
idstringThe template id.
Response
The template.
data.templateTemplatedata.editablebooleanWhether it can still be changed (draft or rejected).
data.usageobject{ sent, skipped }: how often it went out.
curl https://coplace.io/api/v1/templates/<id> \ -H "Authorization: Bearer $COPLACE_KEY"{ "data": { "template": { "id": "…", "name": "…", "language": "…", "category": "UTILITY", "status": "draft", "body": "…", "rejectionReason": "…", "createdAt": "…", "updatedAt": "…" }, "editable": true, "usage": {} }}Edit a draft template
PATCH/api/v1/templates/{id}
Key role admin or above
Changes a template that has not been submitted. Once submitted, its name and language are fixed at Meta — edit the text and submit again as a new version instead.
Path parameters
idstringThe template id.
Body
bodystringThe text.
headerstringThe header line.
footerstringThe footer.
categorystringWhat Meta charges it as.
UTILITYMARKETINGAUTHENTICATION
Response
The template, updated.
data.templateTemplate
curl -X PATCH https://coplace.io/api/v1/templates/<id> \ -H "Authorization: Bearer $COPLACE_KEY" \ -H "Content-Type: application/json" \ -d '{ "body": "…", "header": "…" }'{ "data": { "template": { "id": "…", "name": "…", "language": "…", "category": "UTILITY", "status": "draft", "body": "…", "rejectionReason": "…", "createdAt": "…", "updatedAt": "…" } }}Ask Meta where a submitted template stands
POST/api/v1/templates/{id}/refresh
Key role admin or above
Re-reads the approval state at Meta and stores it. Returns changed: false when nothing moved, so polling is cheap.
Path parameters
idstringThe template id.
Response
The template and whether its state changed.
data.templateTemplatedata.changedbooleanWhether its state changed.
Refusals
- 409
never_submittedThis template was never submitted — there is nothing to ask about.
curl -X POST https://coplace.io/api/v1/templates/<id>/refresh \ -H "Authorization: Bearer $COPLACE_KEY"{ "data": { "template": { "id": "…", "name": "…", "language": "…", "category": "UTILITY", "status": "draft", "body": "…", "rejectionReason": "…", "createdAt": "…", "updatedAt": "…" }, "changed": true }}Submit a template to Meta for approval
POST/api/v1/templates/{id}/submit
Key role admin or above
External and final. The name is reserved at Meta and a submitted template cannot be withdrawn this way.
Meta almost always answers submitted (pending) and reviews later — poll with POST /templates/{id}/refresh. A rejection comes back with Meta's own reason.
Path parameters
idstringThe template id.
Response
The template with its new state: submitted, or rejected with a reason.
data.templateTemplate
curl -X POST https://coplace.io/api/v1/templates/<id>/submit \ -H "Authorization: Bearer $COPLACE_KEY"{ "data": { "template": { "id": "…", "name": "…", "language": "…", "category": "UTILITY", "status": "draft", "body": "…", "rejectionReason": "…", "createdAt": "…", "updatedAt": "…" } }}