ChatKomodo Docs Home Sign in

API reference · Messaging

Templates

Reusable message texts with personalization tokens such as {first_name}.

List message templates

GET/v1/templates

All templates of the tenant, newest first.

Responses

  • 200Templates
    Response fields
    • templatesarray of objectrequired
    • templates[].idstringrequired
    • templates[].api_key_idstringrequired
      Owning tenant
    • templates[].namestringrequired
    • templates[].message_typestringrequired
      text, image, document, audio or video
    • templates[].bodystring | nullrequired
    • templates[].media_r2_keystring | nullrequired
      Key of an uploaded media file (see /v1/media)
    • templates[].captionstring | nullrequired
    • templates[].created_atintegerrequired
      Unix time in milliseconds
  • 401Missing, invalid or expired credentials
Request
curl "https://api.chatkomodo.com/v1/templates" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/templates', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.get(
    "https://api.chatkomodo.com/v1/templates",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.chatkomodo.com/v1/templates', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "templates": [
    {
      "id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "api_key_id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "name": "Order shipped",
      "message_type": "Hi Sam, your order has shipped.",
      "body": "Hi Sam, your order has shipped.",
      "media_r2_key": "uploads/abc123.jpg",
      "caption": "Hi Sam, your order has shipped.",
      "created_at": 1767225600000
    }
  ]
}

Create a message template

POST/v1/templates

Saves a template. Only name is required; message_type defaults to text.

Request body

  • namestringrequired
    1–100 characters
  • message_typestring
    One of: text, image, document, audio, videoDefault: "text"
  • bodystring | null
    Message text; may contain the personalization tokens used by blasts
    Up to 4 096 characters
  • media_r2_keystring | null
    Key of an uploaded media file (see /v1/media)
    Up to 256 characters
  • captionstring | null
    Up to 1 024 characters

Responses

  • 201Created
    Response fields
    • idstringrequired
  • 400Body is not valid JSON (INVALID_JSON) or fails validation (VALIDATION_FAILED)
  • 401Missing, invalid or expired credentials
  • 403Forbidden for a customer-service agent login (Agent access is not allowed for this operation) and an API key restricted to specific sessions (KEY_SCOPE_FORBIDDEN)
Request
curl -X POST "https://api.chatkomodo.com/v1/templates" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Order shipped",
  "message_type": "text",
  "body": "Hi {{first_name|there}}, your order is on its way."
}'
const res = await fetch('https://api.chatkomodo.com/v1/templates', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Order shipped",
    "message_type": "text",
    "body": "Hi {{first_name|there}}, your order is on its way."
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.post(
    "https://api.chatkomodo.com/v1/templates",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    json={
        "name": "Order shipped",
        "message_type": "text",
        "body": "Hi {{first_name|there}}, your order is on its way.",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('POST', 'https://api.chatkomodo.com/v1/templates', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
    'json' => [
        'name' => 'Order shipped',
        'message_type' => 'text',
        'body' => 'Hi {{first_name|there}}, your order is on its way.',
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 201
{
  "id": "01JA5V6Q8M2H7G4K9P3T0R1S2X"
}

Edit a message template

PATCH/v1/templates/{id}

Edits a template in place (id and created_at are kept). Send only the fields to change; null clears body, media_r2_key and caption.

Path parameters

  • idstringrequired
    Template id

Request body

  • namestring
    1–100 characters
  • message_typestring
    One of: text, image, document, audio, video
  • bodystring | null
    Message text; may contain the personalization tokens used by blasts
    Up to 4 096 characters
  • media_r2_keystring | null
    Key of an uploaded media file (see /v1/media)
    Up to 256 characters
  • captionstring | null
    Up to 1 024 characters

Responses

  • 200Updated
    Response fields
    • okbooleanrequired
  • 400Body is not valid JSON (INVALID_JSON) or fails validation (VALIDATION_FAILED)
  • 401Missing, invalid or expired credentials
  • 403Forbidden for a customer-service agent login (Agent access is not allowed for this operation) and an API key restricted to specific sessions (KEY_SCOPE_FORBIDDEN)
  • 404Template not found, or it belongs to another tenant (NOT_FOUND)
Request
curl -X PATCH "https://api.chatkomodo.com/v1/templates/ID" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Order shipped",
  "message_type": "text",
  "body": "Hi Sam, your order has shipped.",
  "media_r2_key": "uploads/abc123.jpg"
}'
const res = await fetch('https://api.chatkomodo.com/v1/templates/ID', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Order shipped",
    "message_type": "text",
    "body": "Hi Sam, your order has shipped.",
    "media_r2_key": "uploads/abc123.jpg"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.patch(
    "https://api.chatkomodo.com/v1/templates/ID",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    json={
        "name": "Order shipped",
        "message_type": "text",
        "body": "Hi Sam, your order has shipped.",
        "media_r2_key": "uploads/abc123.jpg",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('PATCH', 'https://api.chatkomodo.com/v1/templates/ID', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
    'json' => [
        'name' => 'Order shipped',
        'message_type' => 'text',
        'body' => 'Hi Sam, your order has shipped.',
        'media_r2_key' => 'uploads/abc123.jpg',
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "ok": true
}

Delete a message template

DEL/v1/templates/{id}

Permanently deletes a template.

Path parameters

  • idstringrequired
    Template id

Responses

  • 200Deleted
    Response fields
    • okbooleanrequired
  • 401Missing, invalid or expired credentials
  • 403Forbidden for a customer-service agent login (Agent access is not allowed for this operation) and an API key restricted to specific sessions (KEY_SCOPE_FORBIDDEN)
  • 404Template not found (no code)
Request
curl -X DELETE "https://api.chatkomodo.com/v1/templates/ID" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/templates/ID', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.delete(
    "https://api.chatkomodo.com/v1/templates/ID",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('DELETE', 'https://api.chatkomodo.com/v1/templates/ID', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "ok": true
}