End Users
An end user is your user — the recipient of your utility messages, identified by your own customerUserId. These endpoints bind that ID to an eligible phone number and let your backend look the binding up later.
Signing is the anti-enumeration control
While request signing is enabled (the default), both endpoints run under the pipeline's request signing: only a caller holding your signing secret can probe which numbers are bound and eligible.
Why bind end users
Sends accept an optional customerUserId that is echoed back and recorded with each message — binding makes that association first-class. Bind once at signup or verification, then:
- Look up by
customerUserIdbefore a send to confirm the user has an eligible number on file, then deliver with the Send API. - Look up by phone number to find which of your users it belongs to when processing delivery outcomes.
Binding is tenant-scoped: you only ever see your own bindings.
Bind an end user
Associates a customerUserId with a phone number. The number must already be eligible — binding does not grant eligibility, so an attacker cannot bootstrap it by binding arbitrary numbers.
A user can hold multiple numbers: binding a second number to the same customerUserId adds it. Re-binding an existing pair refreshes its eligibility label.
Body
- Name
APIKey- Type
- string
- Description
Your account API key.
- Name
pipelineID- Type
- string
- Description
A utility pipeline on your account. Used to authenticate and to check eligibility.
- Name
customerUserId- Type
- string
- Description
Your internal ID for the user.
- Name
phone- Type
- string
- Description
The user's phone number, E.164. Canonicalized before binding.
Response fields
- Name
customerUserId- Type
- string
- Description
The bound ID.
- Name
phone- Type
- string
- Description
The canonical E.164 form that was bound.
- Name
eligibility- Type
- string
- Description
The proof the number passed with:
verifiedorallowlist.
Request
{
"APIKey": "<AKEDLY_API_KEY>",
"pipelineID": "<YOUR_PIPELINE_ID>",
"customerUserId": "user_123",
"phone": "+201234567890"
}
Response
{
"status": "success",
"data": {
"customerUserId": "user_123",
"phone": "+201234567890",
"eligibility": "allowlist"
}
}
Look up an end user
Finds a binding by either key. Provide customerUserId to check whether that user has a bound number, or phone to find which user a number belongs to. When both are present, customerUserId wins.
An unknown key is not an error — the call succeeds with bound: false.
Body
- Name
APIKey- Type
- string
- Description
Your account API key.
- Name
pipelineID- Type
- string
- Description
A utility pipeline on your account, used to authenticate the call.
- Name
customerUserId- Type
- string
- Description
Look up by your internal user ID. Provide this or
phone.
- Name
phone- Type
- string
- Description
Look up by phone number, E.164.
Response fields
- Name
bound- Type
- boolean
- Description
Whether a binding exists.
- Name
customerUserId- Type
- string
- Description
The bound user ID. Present when
boundistrue.
- Name
eligibility- Type
- string
- Description
The eligibility label recorded at bind time:
verifiedorallowlist. Present whenboundistrue.
Request
{
"APIKey": "<AKEDLY_API_KEY>",
"pipelineID": "<YOUR_PIPELINE_ID>",
"customerUserId": "user_123"
}
Response
{
"status": "success",
"data": {
"bound": true,
"customerUserId": "user_123",
"eligibility": "allowlist"
}
}
Errors
Authentication, pipeline, and signing errors match the send error reference. Endpoint-specific errors:
| Status | Code | Cause and Solution |
|---|---|---|
| 400 | MISSING_FIELDS | Bind requires both customerUserId and phone. |
| 400 | INVALID_PHONE | Bind only — the number is not valid E.164 after canonicalization. On lookup, an invalid phone surfaces as MISSING_LOOKUP_KEY. |
| 400 | BIND_NOT_ELIGIBLE | The number has no eligibility proof. Add it to the allowlist or verify it with an OTP transaction, then bind. |
| 400 | MISSING_LOOKUP_KEY | Lookup requires phone or customerUserId. |