Find Voicegrams by sender
Returns the most recent completed Voicegrams that a sender left, found by their email address or phone number, newest first.
Returns the most recent completed Voicegrams that a sender left, found by their email address or phone number, newest first. Use it when an automation starts from a contact in another system (a CRM record, say) rather than from a Voicegram id: the id of a row is what the messages endpoints take as {id}.
Pass sender_email or sender_phone. A phone number must be in international format (+14155550123), with the plus sign written as %2B in the query string (a bare + reads as a space). Rows carry no transcript and no audio.
Part of the conversations feature: a workspace it is not available for gets 404 conversation_not_available.
Endpoint
GET /api/v1/voicegrams
Authentication
Bearer Personal Access Token. See Authentication.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
sender_email | string (email) | no | The sender's email address. Matched case-insensitively. |
sender_phone | string | no | The sender's phone number in international format, with the plus sign written as %2B (a bare + in a query string reads as a space). Used when sender_email is not given. |
limit | integer | no | How many Voicegrams to return. Defaults to 10. Values outside the allowed range are clamped to the nearest valid value. |
Example request
curl "https://www.voicegram.io/api/v1/voicegrams?sender_email=value&sender_phone=value&limit=10" \
-H "Authorization: Bearer vg_pat_<your-token>"Responses
Matching Voicegrams, newest first. An empty array when the sender has none.
| Field | Type | Required | Description |
|---|---|---|---|
voicegrams | array of object | yes | |
voicegrams[].id | string | yes | Voicegram identifier. Pass it as {id} to the messages endpoints. |
voicegrams[].created_at | string (date-time) | yes | |
voicegrams[].sender | object | yes | |
voicegrams[].sender.verification_method | enum ("email", "sms", "whatsapp") | yes | The channel the sender used to give their contact information (email, sms or whatsapp). Whether it was confirmed is in contact_verified. The name predates optional verification and is kept so existing integrations keep working. |
voicegrams[].sender.contact_verified | boolean | yes | true when the sender proved they own this email address or phone number by entering a one-time code before recording. false when the verification code was turned off for the widget or campaign: the email or phone is exactly what the sender typed and was never confirmed, so it may be mistyped or belong to someone else. |
voicegrams[].sender.email | string | null | yes | Populated when verification_method=email, null otherwise. Exactly one of email, phone, and whatsapp is populated. |
voicegrams[].sender.phone | string | null | yes | E.164 number, populated when verification_method=sms, null otherwise. Exactly one of email, phone, and whatsapp is populated. |
voicegrams[].sender.whatsapp | string | null | yes | E.164 number, populated when verification_method=whatsapp, null otherwise. Exactly one of email, phone, and whatsapp is populated. |
voicegrams[].channel | object | yes | |
voicegrams[].channel.type | enum ("domain", "campaign") | yes | |
voicegrams[].channel.id | string | yes | |
voicegrams[].channel.name | string | yes | |
voicegrams[].channel.page_url | string | null | yes | Page URL where the Voicegram was recorded. Null for campaign-sourced Voicegrams. |
voicegrams[].dashboard_url | string (uri) | yes | Link to the Voicegram in the Voicegram dashboard, opened on its conversation. Requires signing in. |
{
"voicegrams": [
{
"id": "vg_sample_12345678",
"created_at": "2026-05-13T19:22:00.000Z",
"sender": {
"verification_method": "email",
"contact_verified": true,
"email": "sample.customer@example.com",
"phone": null,
"whatsapp": null
},
"channel": {
"type": "domain",
"id": "sample-domain-id",
"name": "example.com",
"page_url": "https://example.com/pricing"
},
"dashboard_url": "https://voicegram.io/dashboard/inbox/vg_sample_12345678#conversation"
}
]
}
Neither sender_email nor sender_phone was given, or the one given is not an email address or an international phone number (validation_error).
| Field | Type | Required | Description |
|---|---|---|---|
error | enum ("invalid_token", "plan_required", "validation_error", "invalid_url", "invalid_channel_id", "not_found", "rate_limited", "limit_reached", "conflict", "forbidden", "conversation_not_available", "conversation_daily_cap", "conversation_participant_cap", "conversation_not_a_stranger", "internal_error") | yes | Stable error code. |
message | string | no | Human-readable error message. |
reason | string | no | Stable diagnostic string. Only set on invalid_url responses. Treat this as an open set and match on the prefix before the colon when one is present. Bare (colon-less) values: url_parse_failed, scheme_must_be_https, url_must_not_contain_credentials, hostname_is_localhost, dns_lookup_returned_no_addresses. Address/message-suffixed values of the form <reason>: <detail>: host_resolves_to_private_ip: 10.0.0.5, ipv4_is_private_or_loopback: 127.0.0.1, ipv6_is_private_or_loopback: ::1, and dns_lookup_failed: <message>. |
issues | array of object | no | Schema-validation issues. Only set on validation_error responses. Each entry has a path array and a message. |
{
"error": "validation_error",
"message": "Pass sender_email or sender_phone."
}
The PAT is missing, malformed, expired, or revoked.
See Errors for the shared error response shape.
PAT is valid but the account is on the free plan.
See Errors for the shared error response shape.
Conversations are not available for the PAT's workspace yet.
See Errors for the shared error response shape.