Skip to the page

API reference

Make a keyword rule

When an incoming one-to-one text matches, the rule replies with words or a template, tags the person, adds them to a sequence, or sends an automation.matched webhook event, in the order you list them.

POST/v1/automations/rules

When an incoming one-to-one text matches, the rule replies with words or a template, tags the person, adds them to a sequence, or sends an automation.matched webhook event, in the order you list them. Only the first matching rule runs.

match is exact (the whole text is the keyword, ignoring case and punctuation at the ends), starts_with, word (the keyword as a whole word anywhere), contains, or regex. A stop word never matches: it stops the person and nothing else.

Needs a key with the messages:send scope. Keys and scopes

Send an Idempotency-Key so a retry never acts twice. Idempotency

Headers

  • Idempotency-Keystring

    Any string of up to 255 characters, new for each request. A retry with the same key gets the first answer back for 24 hours, with Idempotent-Replayed: true.

    Up to 255 characters.

Request body

  • namestringrequired

    Up to 80 characters.

  • matchstringrequired

    One of exact, starts_with, word, contains, regex.

  • keywordsarray of strings

    Up to 20 items.

  • patternstring

    Up to 500 characters.

  • case_sensitiveboolean
  • actionsarray of anyrequired

    Up to 5 items.

  • enabledboolean
  • positioninteger

    0 to 10,000.

Example

POST/v1/automations/rulesMake a keyword rule →
curl -X POST "https://usebluebot.com/api/v1/automations/rules" \
  -H "Authorization: Bearer $BLUEBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 0f6d8c2e-5b1a-4c7e-9d3f-2a8b6e1c4d70" \
  -d '{
    "name": "Pricing",
    "match": "word",
    "keywords": [
      "price",
      "pricing",
      "cost"
    ],
    "actions": [
      {
        "type": "reply",
        "text": "Our plans start at $29 a month. Want me to send the details?"
      }
    ]
  }'

Response

201: The rule.

  • idstringrequired

    A kw_ id.

    Starts with kw_.

  • object"keyword_rule"required
  • namestringrequired
  • matchstringrequired

    exact (the whole text), starts_with, word (a whole word anywhere), contains, or regex.

    One of exact, starts_with, word, contains, regex.

  • keywordsarray of stringsrequired
  • patternstring or nullrequired

    For regex.

  • case_sensitivebooleanrequired
  • actionsarray of anyrequired
  • positionintegerrequired

    Rules are tried from the lowest position up; the first match wins.

  • enabledbooleanrequired
  • fire_countintegerrequired

    How many texts it answered.

  • last_fired_attimestamp or nullrequired

    When it last matched.

  • created_attimestamprequired

    When it was made.

Response201
{
  "id": "kw_1Hq2LxW9cVbN3mKpRtYs0a",
  "object": "keyword_rule",
  "name": "Pricing",
  "match": "word",
  "keywords": [
    "price",
    "pricing",
    "cost"
  ],
  "pattern": null,
  "case_sensitive": false,
  "actions": [
    {
      "type": "reply",
      "text": "Our plans start at $29 a month. Want me to send the details?",
      "template_id": null
    },
    {
      "type": "tag",
      "tags": [
        "asked-pricing"
      ]
    }
  ],
  "position": 10,
  "enabled": true,
  "fire_count": 0,
  "last_fired_at": null,
  "created_at": "2026-11-02T15:00:00.000Z"
}

Errors

Every refusal has the same envelope and a page of its own. These are the ones this operation can give.

CodeStatusWhat it means
unauthorized401The request carried no key, or a key BlueBot doesn’t know: mistyped, revoked, or a test key sent to the live API.
insufficient_scope403The key doesn’t carry the scope the endpoint needs. Each endpoint’s reference names its scope.
rate_limited429Too many requests. A key may make 120 requests a minute. The RateLimit header says how many are left, and Retry-After how long to wait.
internal500Something went wrong on BlueBot’s side. It was reported. Send the request again; with an Idempotency-Key that is always safe.
invalid_request400Something in the request doesn’t fit: a missing or malformed field, a bad id, or a combination the endpoint refuses. details names each field.
not_found404There is no such thing on this account. Ids are prefixed by kind, so a message id starts with msg_.
limit_reached409The account has as many of something as it may have.
plan_lapsed402The account’s plan isn’t active, so BlueBot isn’t taking new texts. Texts already queued wait and go once the plan is active again.
idempotency_conflict409The Idempotency-Key was used in the last 24 hours with a different request. A key stands for one request.

Try it

Call this operation from the page with your own key. The key stays in this tab and is forgotten when you leave.