SMS Consent
Record proof that a phone number's owner agreed to receive SMS from your company, check a number's consent status before texting it, and upload supporting evidence — the compliance layer behind agent-sent SMS.
All paths on this page are relative to https://api.autessa.com/autessa_poweruser/sms-consent. Every request is a POST with a JSON body. See the Poweruser API overview for authentication and conventions.
The consent model
US carriers require A2P 10DLC senders to hold documented consent for every number they message. In Autessa that works as follows:
- You record consent with
/sms-consent— the phone number, how consent was captured (consentMethod), a description, and optionally an evidence file (a screenshot of the web form, a signed document, a call recording) uploaded via/generate-upload-link. - Autessa reviews it. New records start unapproved; the Autessa
compliance team approves them, or rejects them with
rejectionFeedbackexplaining what to fix before resubmitting. - You check before sending with
/search. A number is safe to message whenhasConsentandisApprovedaretrueandisOptedOutisfalse. - Recipients can opt out (for example by replying STOP). Opt-out is tracked per number and overrides any approval.
Everything is scoped to the poweruser key's linked company — the company ID is derived from the key and cannot be overridden in a request, so you can only ever create or read consent records for your own company.
Consent methods: WEB_FORM (submitted via a web form), USER_INITIATED
(the user texted first — implicit consent), VERBAL (recorded verbal
consent), WRITTEN (signed consent form), OTHER.
Create a consent record
/sms-consentRecords consent for a phone number. Note the path: this is the base
resource path with no suffix. The record starts unapproved and enters the
compliance review queue; poll /search to see when it is
approved.
Request parameters
- Name
phoneNumber- Type
- string
- Description
The phone number consent applies to, in E.164 format (for example
+12065550142).
- Name
consentMethod- Type
- string
- Description
How consent was captured:
WEB_FORM,USER_INITIATED,VERBAL,WRITTEN, orOTHER.
- Name
consentDescription- Type
- string
- Description
What the person agreed to and how — shown to the reviewer.
- Name
evidenceS3Uri- Type
- string
- Description
S3 URI of an uploaded evidence file from
/generate-upload-link.
- Name
termsOfServiceUrl- Type
- string
- Description
URL of the terms of service the person accepted.
- Name
privacyPolicyUrl- Type
- string
- Description
URL of the privacy policy the person accepted.
Response
- Name
consentId- Type
- string
- Description
The new consent record.
- Name
status- Type
- string
- Description
Human-readable status of the record.
- Name
isApproved- Type
- boolean
- Description
Whether the record is approved. Always
falseimmediately after creation — approval happens during compliance review.
- Name
errors- Type
- array<string>
- Description
Error messages, if any occurred.
- cURL
- JavaScript
- Python
curl https://api.autessa.com/autessa_poweruser/sms-consent \
-X POST \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+12065550142",
"consentMethod": "WEB_FORM",
"consentDescription": "Opted in to order updates via the checkout form.",
"evidenceS3Uri": "s3://autessa-files/company-cP2mK7dX4v/consent-8f3a.png",
"termsOfServiceUrl": "https://acme.com/terms",
"privacyPolicyUrl": "https://acme.com/privacy"
}'
const response = await fetch(
'https://api.autessa.com/autessa_poweruser/sms-consent',
{
method: 'POST',
headers: {
'Authorization': process.env.POWERUSER_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
phoneNumber: '+12065550142',
consentMethod: 'WEB_FORM',
consentDescription: 'Opted in to order updates via the checkout form.',
termsOfServiceUrl: 'https://acme.com/terms',
privacyPolicyUrl: 'https://acme.com/privacy'
})
}
);
const { consentId, isApproved } = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/autessa_poweruser/sms-consent',
headers={'Authorization': os.environ['POWERUSER_KEY']},
json={
'phoneNumber': '+12065550142',
'consentMethod': 'WEB_FORM',
'consentDescription': 'Opted in to order updates via the checkout form.',
'termsOfServiceUrl': 'https://acme.com/terms',
'privacyPolicyUrl': 'https://acme.com/privacy'
}
)
consent = response.json()
{
"consentId": "sC7wJ2fN9q",
"status": "PENDING_APPROVAL",
"isApproved": false,
"errors": []
}
Search consent by phone number
/sms-consent/searchLooks up the consent status of a phone number within your company. Call this
before sending SMS: the number is messageable only when hasConsent and
isApproved are true and isOptedOut is false.
Request parameters
- Name
phoneNumber- Type
- string
- Description
The phone number to look up, in E.164 format.
Response
- Name
hasConsent- Type
- boolean
- Description
Whether a consent record exists for this number.
- Name
isApproved- Type
- boolean
- Description
Whether the record passed compliance review.
- Name
isOptedOut- Type
- boolean
- Description
Whether the recipient has since opted out. Opt-out overrides approval.
- Name
consentMethod- Type
- string
- Description
How consent was captured:
WEB_FORM,USER_INITIATED,VERBAL,WRITTEN, orOTHER.
- Name
consentedAt- Type
- string
- Description
ISO-8601 timestamp of when consent was recorded.
- Name
rejectionFeedback- Type
- string
- Description
Reviewer feedback when the record was rejected — explains what to change before resubmitting.
- Name
errors- Type
- array<string>
- Description
Error messages, if any occurred.
- cURL
- JavaScript
- Python
curl https://api.autessa.com/autessa_poweruser/sms-consent/search \
-X POST \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{ "phoneNumber": "+12065550142" }'
const response = await fetch(
'https://api.autessa.com/autessa_poweruser/sms-consent/search',
{
method: 'POST',
headers: {
'Authorization': process.env.POWERUSER_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ phoneNumber: '+12065550142' })
}
);
const { hasConsent, isApproved, isOptedOut } = await response.json();
const canText = hasConsent && isApproved && !isOptedOut;
import os
import requests
response = requests.post(
'https://api.autessa.com/autessa_poweruser/sms-consent/search',
headers={'Authorization': os.environ['POWERUSER_KEY']},
json={'phoneNumber': '+12065550142'}
)
data = response.json()
can_text = data['hasConsent'] and data['isApproved'] and not data['isOptedOut']
{
"hasConsent": true,
"isApproved": true,
"isOptedOut": false,
"consentMethod": "WEB_FORM",
"consentedAt": "2026-06-15T10:04:31",
"rejectionFeedback": null,
"errors": []
}
Generate an evidence upload link
/sms-consent/generate-upload-linkReturns a pre-signed S3 URL for uploading a consent evidence file (a form
screenshot, a signed document, and so on). Upload the file with an HTTP
PUT to uploadUrl using the returned mimeType as Content-Type, then
pass s3Uri as evidenceS3Uri when creating the record.
The S3 path is scoped to your company.
Request parameters
- Name
fileExtension- Type
- string
- Description
"png","jpg","jpeg", or"pdf".
Response
- Name
uploadUrl- Type
- string
- Description
Pre-signed URL;
PUTthe file bytes here.
- Name
s3Uri- Type
- string
- Description
S3 URI to reference the uploaded file as
evidenceS3Uri.
- Name
mimeType- Type
- string
- Description
MIME type to send as
Content-Typeon the upload.
- Name
expiresInSeconds- Type
- integer
- Description
How long the upload URL stays valid.
- Name
errors- Type
- array<string>
- Description
Error messages, if any occurred.
curl https://api.autessa.com/autessa_poweruser/sms-consent/generate-upload-link \
-X POST \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{ "fileExtension": "png" }'
# Then upload the evidence file:
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: image/png" \
--data-binary '@consent-form-screenshot.png'
{
"uploadUrl": "https://s3.amazonaws.com/autessa-files/...",
"s3Uri": "s3://autessa-files/company-cP2mK7dX4v/consent-8f3a.png",
"mimeType": "image/png",
"expiresInSeconds": 3600,
"errors": []
}
Errors
| Status | When |
|---|---|
200 | Success — check errors for validation messages (missing or malformed phoneNumber, missing consentMethod). |
401 | Invalid or missing poweruser key. |
403 | Scoped key without the endpoint in its allow-list. |
408 | Server-side error; errors contains the message. |