Phone Verifications
Returns the account's phone-verification attempts, most recent first. status answers only whether ownership of the number was proven — an attempt refused at the line level stays pending and carries the refusal in failure_type instead, so filter on failure_type semantics via the returned records rather than assuming a failed status.
Failure details are provider-neutral buckets: failure_type, retriable, and category. A line_untrusted or line_not_eligible attempt is retriable with a different number — the line, not the person, was refused. Page through with the standard page / per_page parameters.
export FRAME_API_KEY='sk_sandbox_...'
The Phone Verification object
Attributes
Unique identifier for the phone verification.
Object type identifier. Always phone_verification.
Whether ownership of the number was proven. One of pending, verified, failed, or expired. An attempt refused at the line level keeps pending — the refusal is carried by failure_type, not by status.
The phone number this attempt verifies.
The attempt's recorded outcome, as a provider-neutral bucket. One of challenge_failed, line_not_eligible, line_untrusted, otp_not_completed, otp_attempts_exceeded, session_out_of_order, validation_error, external_api_error, or unclassified. null while no outcome is recorded.
Whether retrying can change the outcome — true when a different phone number (or waiting out a transient fault) can succeed. null when failure_type is null.
The remediation class behind retriable. One of retriable_with_new_data, terminal, transient, or unclassified. A line-level refusal is retriable_with_new_data: the line, not the person, was refused.
ID of the account this verification belongs to.
true if live mode, false if test mode.
Unix timestamp of when the attempt was created.
Unix timestamp after which this attempt can no longer be confirmed.
{
"id": "b3e2c1d0-4f5a-6789-bcde-f01234567893",
"object": "phone_verification",
"status": "pending",
"phone_number": "+15555550123",
"failure_type": null,
"retriable": null,
"category": null,
"account": "99c6b0da-2570-42a7-838a-5eaa318b07df",
"livemode": false,
"created": 1721010605,
"expires": 1721014205
}
List phone verifications
Returns the account's phone-verification attempts, most recent first. status answers only whether ownership of the number was proven — an attempt refused at the line level stays pending and carries the refusal in failure_type instead, so filter on failure_type semantics via the returned records rather than assuming a failed status.
Failure details are provider-neutral buckets: failure_type, retriable, and category. A line_untrusted or line_not_eligible attempt is retriable with a different number — the line, not the person, was refused. Page through with the standard page / per_page parameters.
Path parameters
The ID of the account.
Query parameters
Only return attempts with this status (e.g. pending, verified).
Page number (default 1).
Items per page (default 10, max 100).
Returns
A dictionary with a data array of phone-verification attempts, most recent first, and pagination meta.
curl --request GET \
--url https://api.framepayments.com/v1/accounts/a70cd72f-e74a-40f2-96a2-3f60714aac4a/phone_verifications \
--header 'Authorization: Bearer API_KEY'
{
"meta": {
"page": 1,
"url": "/v1/accounts/00000000-0000-4000-8000-000000000001/phone_verifications?status=&page=&per_page=",
"has_more": false,
"prev": null,
"next": null
},
"data": [
{
"id": "00000000-0000-4000-8000-000000000002",
"object": "phone_verification",
"status": "verified",
"phone_number": "+17742345678",
"failure_type": null,
"retriable": null,
"category": null,
"account": "00000000-0000-4000-8000-000000000001",
"livemode": false,
"created": 1745020800,
"expires": 1745107500
},
{
"id": "00000000-0000-4000-8000-000000000003",
"object": "phone_verification",
"status": "pending",
"phone_number": "+17742345678",
"failure_type": "line_untrusted",
"retriable": true,
"category": "retriable_with_new_data",
"account": "00000000-0000-4000-8000-000000000001",
"livemode": false,
"created": 1744934400,
"expires": 1745108040
}
]
}
Create phone verification
Initiates a phone verification for the given account by sending a one-time passcode (OTP) via SMS to the account's phone number. frameOS evaluates mobile identity signals in the background — including the number's trust score, carrier information, and behavioral characteristics — to determine whether the user presents a risk.
If you are using onboarding sessions, frameOS handles the full OTP flow — sending, delivery, and validation — with no additional integration required. Call this endpoint directly only when managing the verification flow outside of an onboarding session.
Path parameters
The ID of the account to initiate phone verification for.
Body parameters
Verification type (e.g. twilio, prove)
The phone number to verify. This is the number that will receive the OTP and be linked to the account holder's identity within Frame.
Date of birth (saved to account profile if provided)
Returns
Phone verification created and OTP sent to the account's phone number.
curl --request POST \
--url https://api.framepayments.com/v1/accounts/a70cd72f-e74a-40f2-96a2-3f60714aac4a/phone_verifications \
--header 'Authorization: Bearer API_KEY'
{
"id": "00000000-0000-4000-8000-000000000001",
"type": "phone",
"status": "pending",
"provider": "sandbox",
"sandbox": {
"expected_codes": [
"123456",
"000000",
"111111"
]
}
}
Confirm phone verification
Confirms a phone verification by validating the OTP code sent to the account's phone number. If the code is correct and has not expired, the phone number is linked to the account holder's identity within Frame and the verification status transitions to verified.
If the number passes verification, the account holder is authenticated and their phone number is linked to their identity. If the number shows suspicious characteristics, additional verification steps may be introduced or the evaluation may be flagged for review.
Path parameters
The ID of the account the phone verification belongs to.
The ID of the phone verification to confirm.
Body parameters
The one-time passcode (OTP) sent via SMS to the account holder's phone number.
Returns
Phone verification confirmed. The phone number is now linked to the account holder's identity and the verification status is verified.
curl --request POST \
--url https://api.framepayments.com/v1/accounts/a70cd72f-e74a-40f2-96a2-3f60714aac4a/phone_verifications/a70cd72f-e74a-40f2-96a2-3f60714aac4a/confirm \
--header 'Authorization: Bearer API_KEY'
{
"id": "00000000-0000-4000-8000-000000000001",
"status": "verified",
"provider": "twilio"
}
Retrieve a phone verification
Retrieves one phone-verification attempt. The record carries the attempt's recorded outcome as provider-neutral buckets (failure_type, retriable, category) alongside its ownership status — a verified attempt can still carry a failed prefill outcome, and a line-refused attempt stays pending with the refusal in failure_type.
These are the same fields the account.phone_verification.verified / account.phone_verification.failed webhook events deliver, rendered from the same serializer.
Path parameters
The ID of the account.
The ID of the phone verification.
Returns
The phone-verification attempt.
curl --request GET \
--url https://api.framepayments.com/v1/accounts/a70cd72f-e74a-40f2-96a2-3f60714aac4a/phone_verifications/a70cd72f-e74a-40f2-96a2-3f60714aac4a \
--header 'Authorization: Bearer API_KEY'
{
"id": "00000000-0000-4000-8000-000000000001",
"object": "phone_verification",
"status": "pending",
"phone_number": "+17742345678",
"failure_type": "line_untrusted",
"retriable": true,
"category": "retriable_with_new_data",
"account": "00000000-0000-4000-8000-000000000002",
"livemode": false,
"created": 1745107200,
"expires": 1745108040
}