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.
/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.
Send an Idempotency-Key so a retry never acts twice.
Headers
Idempotency-KeystringAny 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
namestringrequiredUp to 80 characters.
matchstringrequiredOne of
exact,starts_with,word,contains,regex.keywordsarray of stringsUp to 20 items.
patternstringUp to 500 characters.
case_sensitivebooleanactionsarray of anyrequiredUp to 5 items.
enabledbooleanpositioninteger0 to 10,000.
Example
/v1/automations/rulescurl -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.
idstringrequiredA kw_ id.
Starts with
kw_.object"keyword_rule"requirednamestringrequiredmatchstringrequiredexact(the whole text),starts_with,word(a whole word anywhere),contains, orregex.One of
exact,starts_with,word,contains,regex.keywordsarray of stringsrequiredpatternstring or nullrequiredFor
regex.case_sensitivebooleanrequiredactionsarray of anyrequiredpositionintegerrequiredRules are tried from the lowest position up; the first match wins.
enabledbooleanrequiredfire_countintegerrequiredHow many texts it answered.
last_fired_attimestamp or nullrequiredWhen it last matched.
created_attimestamprequiredWhen it was made.
{
"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.
| Code | Status | What it means |
|---|---|---|
| 401 | The request carried no key, or a key BlueBot doesn’t know: mistyped, revoked, or a test key sent to the live API. | |
| 403 | The key doesn’t carry the scope the endpoint needs. Each endpoint’s reference names its scope. | |
| 429 | Too 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. | |
| 500 | Something went wrong on BlueBot’s side. It was reported. Send the request again; with an Idempotency-Key that is always safe. | |
| 400 | Something in the request doesn’t fit: a missing or malformed field, a bad id, or a combination the endpoint refuses. details names each field. | |
| 404 | There is no such thing on this account. Ids are prefixed by kind, so a message id starts with msg_. | |
| 409 | The account has as many of something as it may have. | |
| 402 | The 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. | |
| 409 | The 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.