Send a text
Text one contact from your organization's own number, like a quote on its way or a visit confirmed, and get their reply in your Inbox.
POST /v1/texts sends one text to one contact from your organization's texting number. Use it for texts your website sends one person at a time: "Your quote is ready", "See you at the studio tomorrow at 3". With more than one number, it goes from the number the contact is on, or your default. The text is kept in the contact's conversation in your Inbox, and their reply arrives there too.
Your organization needs its own texting number first. You request it under Settings → Messaging. See Text messaging.
Text a contact
The contact is saved first, the same way as PUT /v1/contacts, and the text goes to the first phone number you send.
curl -X POST https://api.lahuta.org/v1/texts \
-H "X-Api-Key: $LAHUTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"key": "commission-quote:2291",
"contact": {
"kind": "person",
"firstName": "Hannah",
"lastName": "Lindqvist",
"phones": [{ "label": "Mobile", "value": "+15035550131" }]
},
"body": "Hi Hannah, the quote for your eight dinner plates is ready. Check your email, or reply here with any questions."
}'{
"messageId": "0197b36b-2a14-7f31-9c07-5e8d1b4a6f20",
"conversationId": "0197a9d4-0b77-7c52-8e19-3f6a2d9c1b84",
"contactId": "0197b36a-4e11-7a53-9f02-6b1c8e4d2a37",
"opened": true
}| Field | Required | What it does |
|---|---|---|
key | Yes | Your name for this text. Sending it again sends nothing and returns the same text with "opened": false. See Idempotency |
contact | Yes | Who it's for. It needs at least one number in phones, in E.164. The text goes to the first number, and to nobody else |
body | Yes | Plain text, 1 to 1,400 characters |
Things to know:
- It's sent as written. There are no personal values, so put the person's name in yourself. A body with a
{{lahuta:…}}value in it is refused. - It carries your organization's name. It starts with your organization's name and ends with "Reply STOP to opt out", unless your message already says how to stop. Both count toward the 1,600 characters a text can have, which is why
bodystops at 1,400. - Its links are tracked. Each link goes out as a short link, like
lahuta.org/l/x7Kq2mPa, that opens the page you wrote. A workflow can wait for the contact to tap it. - It's kept in your Inbox. The text shows in the contact's conversation, sent by your organization. When they reply, your team sees it there and can answer.
conversationIdis that conversation. - The number has to be in the call. A contact who already has a phone number in Lahuta still needs one in
contact.phones. - It's for one person at a time. To text a list, use a text campaign.
- It doesn't need marketing consent. A text sent this way is treated like a reply from your inbox, about something the person asked for. Campaigns and workflow texts need recorded consent.
Errors
| Error | When | What to do |
|---|---|---|
422 NoPhone | contact.phones is missing or empty | Include at least one number |
409 NoTextingNumber | Your organization doesn't have its own texting number yet | Request one under Settings → Messaging. See Text messaging |
409 OptedOut | The number is on your opted out list, usually because it replied STOP | Don't text them again. Only they can take back a STOP, by texting START to any of your numbers |
429 TooManyRequests | More than 200 texts this hour | Wait retryAfterSeconds. See Rate limits |
400 | The body is empty, longer than 1,400 characters or has a {{lahuta:…}} value, or a phone number isn't in E.164 | Check the body and the number's format |
When a text is refused, nothing is sent and the contact isn't saved.
See Texts in the API reference for every field.