Phone numbers
Phone numbers for calls and SMS: browse countries and prices, buy one (countries that regulate numbers ask for the registrant’s identity first: KYC), set where inbound calls go and turn SMS on. Owners and admins manage them; numbers bill monthly from the balance.
Countries and prices
Section titled “Countries and prices”/v1/phone-numbers/countriesWhere numbers can be bought, per number type: monthly price (cents), whether KYC is needed, SMS and stock.
Response 200
data []
codestringrequiredISO 3166-1 alpha-2.
needsKycbooleanrequiredtypesobject[]requiredThe default type first.
types
numberTypestringrequiredmonthlyPriceintegerrequiredCents of euro per month.
needsKycbooleanrequiredsmsbooleanrequiredcallsbooleanrequiredinStockbooleanrequiredpreOrderablebooleanrequiredOut of stock but orderable through KYC (usually 2 to 4 weeks).
curl "https://api.marsial.dev/v1/phone-numbers/countries" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/phone-numbers/countries', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/phone-numbers/countries", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]Search available numbers
Section titled “Search available numbers”/v1/phone-numbers/availableLive inventory of a country. Any result can be bought exactly with POST /phone-numbers (except in countries that need KYC).
Parameters
countrystringrequiredISO 3166-1 alpha-2 (GET /v1/phone-numbers/countries).
numberTypestringlocal, mobile, national or toll_free; the country's default when left out.
areaCodestringArea code (91, 415) or a city name.
localitystringA city of the country.
containsstringDigits the number must contain.
smsstringOnly numbers that can also send SMS.
limitinteger
Response 200
data []
phoneNumberstringrequiredE.164.
featuresstring[]requiredvoice, sms, mms…
localitystringbestEffortbooleanrequiredAdded because too few matched: may be outside the requested area.
curl "https://api.marsial.dev/v1/phone-numbers/available?country=GB&numberType=mobile&sms=true" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/phone-numbers/available?country=GB&numberType=mobile&sms=true', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/phone-numbers/available?country=GB&numberType=mobile&sms=true", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]List a profile’s numbers
Section titled “List a profile’s numbers”/v1/phone-numbersActive numbers and those in review (declined ones stay listed for 30 days, with the reason).
Parameters
profileIdstringThe profile whose numbers to list; without it, every profile's.
Response 200
data []
idstringrequirednum_…
profileIdstringrequiredphoneNumberstring | nullrequiredE.164; null until the carrier assigns it.
countrystringrequirednumberTypestringstatusstringrequiredpending_regulatorywhile the carrier reviews the KYC;regulatory_declinedwith the reason inregulatory.monthlyPriceintegerCents of euro per month, fixed when it was bought.
callsobjectrequiredcalls
enabledbooleanrequiredforwardTostringWhere inbound calls go: tel:+E164, sip:… or wss://….
voicemailEnabledbooleanvoicemailGreetingstringrecordingEnabledbooleantranscriptionEnabledbooleantranscriptionLanguagestringbusinessHoursEnabledbooleanbusinessHoursTimezonestringbusinessHoursobject[]businessHours
dayintegerrequiredopenstringrequiredclosestringrequired
blockedCallersstring[]forwardCallerIdstring
smsobjectrequiredsms
enabledbooleanrequiredcapablebooleansendApprovedbooleanTexts deliver (US numbers need a carrier registration first).
domesticOnlybooleanCan only text numbers of its own country.
regulatoryobjectregulatory
declineReasonstringreviewCommentstringactionRequiredbooleanrequiredidVerificationUrlstringIdentity check for the registrant, once the order is placed (some countries).
createdAtstring (date-time)activatedAtstring (date-time)smsNoticestringAfter turning SMS on, what else it needs.
curl "https://api.marsial.dev/v1/phone-numbers?profileId=prf_8f2k4d" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/phone-numbers?profileId=prf_8f2k4d', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/phone-numbers?profileId=prf_8f2k4d", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]Buy a number
Section titled “Buy a number”/v1/phone-numbersOwners and admins. Needs at least one month of the number in the balance. Countries that regulate numbers answer 202 kyc_required: send the registrant's identity with POST /phone-numbers/kyc.
Body
profileIdstringrequiredcountrystringrequirednumberTypestringlocal, mobile, national or toll_free; the country's default when left out.
phoneNumberstringOne exact number from GET /v1/phone-numbers/available. Not for countries that need KYC.
areaCodestringAny number in this area (when phoneNumber is left out).
smsbooleanPick a number that can send SMS and turn SMS on.
idempotencyKeystringSend the same value when retrying, so a retry never buys a second number.
Response 201
data
idstringrequirednum_…
profileIdstringrequiredphoneNumberstring | nullrequiredE.164; null until the carrier assigns it.
countrystringrequirednumberTypestringstatusstringrequiredpending_regulatorywhile the carrier reviews the KYC;regulatory_declinedwith the reason inregulatory.monthlyPriceintegerCents of euro per month, fixed when it was bought.
callsobjectrequiredcalls
enabledbooleanrequiredforwardTostringWhere inbound calls go: tel:+E164, sip:… or wss://….
voicemailEnabledbooleanvoicemailGreetingstringrecordingEnabledbooleantranscriptionEnabledbooleantranscriptionLanguagestringbusinessHoursEnabledbooleanbusinessHoursTimezonestringbusinessHoursobject[]businessHours
dayintegerrequiredopenstringrequiredclosestringrequired
blockedCallersstring[]forwardCallerIdstring
smsobjectrequiredsms
enabledbooleanrequiredcapablebooleansendApprovedbooleanTexts deliver (US numbers need a carrier registration first).
domesticOnlybooleanCan only text numbers of its own country.
regulatoryobjectregulatory
declineReasonstringreviewCommentstringactionRequiredbooleanrequiredidVerificationUrlstringIdentity check for the registrant, once the order is placed (some countries).
createdAtstring (date-time)activatedAtstring (date-time)smsNoticestringAfter turning SMS on, what else it needs.
curl -X POST "https://api.marsial.dev/v1/phone-numbers" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "profileId": "prf_8f2k4d", "country": "GB", "numberType": "mobile", "sms": true }'const res = await fetch('https://api.marsial.dev/v1/phone-numbers', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "profileId": "prf_8f2k4d", "country": "GB", "numberType": "mobile", "sms": true }),});const { data } = await res.json();import os, requests
res = requests.post( "https://api.marsial.dev/v1/phone-numbers", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "profileId": "prf_8f2k4d", "country": "GB", "numberType": "mobile", "sms": True },)data = res.json()["data"]The KYC form of a country
Section titled “The KYC form of a country”/v1/phone-numbers/kycWhat the carrier needs to know about whoever holds the number: text, date, address, documents, and sometimes an identity check done later (action).
Parameters
countrystringrequirednumberTypestringlocal, mobile, national or toll_free; the country's default when left out.
Response 200
data
countrystringrequirednumberTypestringfieldsobject[]requiredfields
requirementIdstringrequiredlabelstringrequiredkindstringrequiredfile: upload it first;action: an identity check done later through a link.descriptionstringexamplestringlocalTostringISO country the value must be local to.
curl "https://api.marsial.dev/v1/phone-numbers/kyc?country=ES" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/phone-numbers/kyc?country=ES', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/phone-numbers/kyc?country=ES", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]Order a number with KYC
Section titled “Order a number with KYC”/v1/phone-numbers/kycOrders the number of a regulated country with the registrant's identity. It waits in the carrier's review (pending_regulatory, usually 1 to 3 business days) and bills only once active. When the form had an identity check, the number gets regulatory.idVerificationUrl to send to the registrant.
Body
profileIdstringrequiredcountrystringrequirednumberTypestringlocal, mobile, national or toll_free; the country's default when left out.
valuesobjectrequirementId → value, for
textanddatefields.documentsobject[]documents
requirementIdstringrequireddocumentIdstringrequiredFrom POST /v1/phone-numbers/kyc/documents.
addressobjectaddress
requirementIdstringrequiredcountryCodestringrequiredstreetAddressstringrequiredextendedAddressstringlocalitystringrequiredadministrativeAreastringpostalCodestringrequired
endUserFirstNamestringLegal first name, when the form has an identity check (
action).endUserLastNamestringareaCodestringphoneNumberstringsmsbooleanpreOrderbooleanAccept sourcing a number when the area has no stock (usually 2 to 4 weeks).
submissionIdstringSend the same value when retrying, so a retry never orders a second number.
Response 202
data
numbersobject[]requirednumbers
idstringrequirednum_…
profileIdstringrequiredphoneNumberstring | nullrequiredE.164; null until the carrier assigns it.
countrystringrequirednumberTypestringstatusstringrequiredpending_regulatorywhile the carrier reviews the KYC;regulatory_declinedwith the reason inregulatory.monthlyPriceintegerCents of euro per month, fixed when it was bought.
callsobjectrequiredcalls
enabledbooleanrequiredforwardTostringWhere inbound calls go: tel:+E164, sip:… or wss://….
voicemailEnabledbooleanvoicemailGreetingstringrecordingEnabledbooleantranscriptionEnabledbooleantranscriptionLanguagestringbusinessHoursEnabledbooleanbusinessHoursTimezonestringbusinessHoursobject[]businessHours
dayintegerrequiredopenstringrequiredclosestringrequired
blockedCallersstring[]forwardCallerIdstring
smsobjectrequiredsms
enabledbooleanrequiredcapablebooleansendApprovedbooleanTexts deliver (US numbers need a carrier registration first).
domesticOnlybooleanCan only text numbers of its own country.
regulatoryobjectregulatory
declineReasonstringreviewCommentstringactionRequiredbooleanrequiredidVerificationUrlstringIdentity check for the registrant, once the order is placed (some countries).
createdAtstring (date-time)activatedAtstring (date-time)smsNoticestringAfter turning SMS on, what else it needs.
preOrderbooleanrequiredThe carrier sources the number (usually 2 to 4 weeks); nothing is billed until it is active.
curl -X POST "https://api.marsial.dev/v1/phone-numbers/kyc" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "profileId": "prf_8f2k4d", "country": "ES", "values": { "d7e8f9a0-…": "Acme SL" }, "documents": [ { "requirementId": "e8f9a0b1-…", "documentId": "kdoc_…" } ], "address": { "requirementId": "f9a0b1c2-…", "countryCode": "ES", "streetAddress": "Gran Vía 1", "locality": "Madrid", "postalCode": "28013" } }'const res = await fetch('https://api.marsial.dev/v1/phone-numbers/kyc', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "profileId": "prf_8f2k4d", "country": "ES", "values": { "d7e8f9a0-…": "Acme SL" }, "documents": [ { "requirementId": "e8f9a0b1-…", "documentId": "kdoc_…" } ], "address": { "requirementId": "f9a0b1c2-…", "countryCode": "ES", "streetAddress": "Gran Vía 1", "locality": "Madrid", "postalCode": "28013" } }),});const { data } = await res.json();import os, requests
res = requests.post( "https://api.marsial.dev/v1/phone-numbers/kyc", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "profileId": "prf_8f2k4d", "country": "ES", "values": { "d7e8f9a0-…": "Acme SL" }, "documents": [ { "requirementId": "e8f9a0b1-…", "documentId": "kdoc_…" } ], "address": { "requirementId": "f9a0b1c2-…", "countryCode": "ES", "streetAddress": "Gran Vía 1", "locality": "Madrid", "postalCode": "28013" } },)data = res.json()["data"]Upload a KYC document
Section titled “Upload a KYC document”/v1/phone-numbers/kyc/documentsOne file (PDF, JPEG or PNG, up to 4 MB, in base64). It goes straight to the carrier; Marsial keeps nothing. Use the returned id in POST /phone-numbers/kyc.
Body
filenamestringrequiredcontentTypestringrequireddatastringrequiredThe file in base64, up to 4 MB. For an ID card, both sides in one file.
Response 201
data
documentIdstringrequiredkdoc_…
curl -X POST "https://api.marsial.dev/v1/phone-numbers/kyc/documents" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filename": "id.pdf", "contentType": "application/pdf", "data": "JVBERi0xLjQK…" }'const res = await fetch('https://api.marsial.dev/v1/phone-numbers/kyc/documents', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "filename": "id.pdf", "contentType": "application/pdf", "data": "JVBERi0xLjQK…" }),});const { data } = await res.json();import os, requests
res = requests.post( "https://api.marsial.dev/v1/phone-numbers/kyc/documents", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "filename": "id.pdf", "contentType": "application/pdf", "data": "JVBERi0xLjQK…" },)data = res.json()["data"]Get a number
Section titled “Get a number”/v1/phone-numbers/{id}Parameters
idstringrequired
Response 200
data
idstringrequirednum_…
profileIdstringrequiredphoneNumberstring | nullrequiredE.164; null until the carrier assigns it.
countrystringrequirednumberTypestringstatusstringrequiredpending_regulatorywhile the carrier reviews the KYC;regulatory_declinedwith the reason inregulatory.monthlyPriceintegerCents of euro per month, fixed when it was bought.
callsobjectrequiredcalls
enabledbooleanrequiredforwardTostringWhere inbound calls go: tel:+E164, sip:… or wss://….
voicemailEnabledbooleanvoicemailGreetingstringrecordingEnabledbooleantranscriptionEnabledbooleantranscriptionLanguagestringbusinessHoursEnabledbooleanbusinessHoursTimezonestringbusinessHoursobject[]businessHours
dayintegerrequiredopenstringrequiredclosestringrequired
blockedCallersstring[]forwardCallerIdstring
smsobjectrequiredsms
enabledbooleanrequiredcapablebooleansendApprovedbooleanTexts deliver (US numbers need a carrier registration first).
domesticOnlybooleanCan only text numbers of its own country.
regulatoryobjectregulatory
declineReasonstringreviewCommentstringactionRequiredbooleanrequiredidVerificationUrlstringIdentity check for the registrant, once the order is placed (some countries).
createdAtstring (date-time)activatedAtstring (date-time)smsNoticestringAfter turning SMS on, what else it needs.
curl "https://api.marsial.dev/v1/phone-numbers/num_…" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/phone-numbers/num_…', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/phone-numbers/num_…", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]Release a number
Section titled “Release a number”/v1/phone-numbers/{id}Owners and admins. Gives the number back and stops billing it; a number in review or a pre-order is cancelled. It cannot be recovered.
Parameters
idstringrequired
Response 204
No content
curl -X DELETE "https://api.marsial.dev/v1/phone-numbers/num_…" \ -H "Authorization: Bearer $MARSIAL_API_KEY"await fetch('https://api.marsial.dev/v1/phone-numbers/num_…', { method: 'DELETE', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});import os, requests
requests.delete( "https://api.marsial.dev/v1/phone-numbers/num_…", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)Set up inbound calls
Section titled “Set up inbound calls”/v1/phone-numbers/{id}/callsWhere calls go (a phone, a SIP address or an AI voice agent over wss://), voicemail, business hours, blocked callers, recording and transcription. Only the fields sent change.
Parameters
idstringrequired
Body
enabledbooleanfalse turns calls off on the number (settings are kept).
forwardTostring | ""Where inbound calls go: tel:+E164, sip:… or wss://… (an AI voice agent). Empty clears it.
voicemailEnabledbooleanvoicemailGreetingstringrecordingEnabledbooleanRecords calls (a consent notice plays first).
transcriptionEnabledbooleantranscriptionLanguagestringbusinessHoursEnabledbooleanbusinessHoursTimezonestringIANA time zone, e.g. Europe/Madrid.
businessHoursobject[]businessHours
dayintegerrequired0 is Sunday.
openstringrequiredclosestringrequired
blockedCallersstring[]Replaces the whole list.
forwardCallerIdstring
Response 200
data
idstringrequirednum_…
profileIdstringrequiredphoneNumberstring | nullrequiredE.164; null until the carrier assigns it.
countrystringrequirednumberTypestringstatusstringrequiredpending_regulatorywhile the carrier reviews the KYC;regulatory_declinedwith the reason inregulatory.monthlyPriceintegerCents of euro per month, fixed when it was bought.
callsobjectrequiredcalls
enabledbooleanrequiredforwardTostringWhere inbound calls go: tel:+E164, sip:… or wss://….
voicemailEnabledbooleanvoicemailGreetingstringrecordingEnabledbooleantranscriptionEnabledbooleantranscriptionLanguagestringbusinessHoursEnabledbooleanbusinessHoursTimezonestringbusinessHoursobject[]businessHours
dayintegerrequiredopenstringrequiredclosestringrequired
blockedCallersstring[]forwardCallerIdstring
smsobjectrequiredsms
enabledbooleanrequiredcapablebooleansendApprovedbooleanTexts deliver (US numbers need a carrier registration first).
domesticOnlybooleanCan only text numbers of its own country.
regulatoryobjectregulatory
declineReasonstringreviewCommentstringactionRequiredbooleanrequiredidVerificationUrlstringIdentity check for the registrant, once the order is placed (some countries).
createdAtstring (date-time)activatedAtstring (date-time)smsNoticestringAfter turning SMS on, what else it needs.
curl -X PATCH "https://api.marsial.dev/v1/phone-numbers/num_…/calls" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "forwardTo": "tel:+34600111222", "recordingEnabled": true }'const res = await fetch('https://api.marsial.dev/v1/phone-numbers/num_…/calls', { method: 'PATCH', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "forwardTo": "tel:+34600111222", "recordingEnabled": true }),});const { data } = await res.json();import os, requests
res = requests.patch( "https://api.marsial.dev/v1/phone-numbers/num_…/calls", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "forwardTo": "tel:+34600111222", "recordingEnabled": True },)data = res.json()["data"]Turn SMS on or off
Section titled “Turn SMS on or off”/v1/phone-numbers/{id}/smsOnly numbers that can text. US numbers also need a carrier registration (10DLC) that Marsial does not offer yet.
Parameters
idstringrequired
Body
enabledbooleanrequired
Response 200
data
idstringrequirednum_…
profileIdstringrequiredphoneNumberstring | nullrequiredE.164; null until the carrier assigns it.
countrystringrequirednumberTypestringstatusstringrequiredpending_regulatorywhile the carrier reviews the KYC;regulatory_declinedwith the reason inregulatory.monthlyPriceintegerCents of euro per month, fixed when it was bought.
callsobjectrequiredcalls
enabledbooleanrequiredforwardTostringWhere inbound calls go: tel:+E164, sip:… or wss://….
voicemailEnabledbooleanvoicemailGreetingstringrecordingEnabledbooleantranscriptionEnabledbooleantranscriptionLanguagestringbusinessHoursEnabledbooleanbusinessHoursTimezonestringbusinessHoursobject[]businessHours
dayintegerrequiredopenstringrequiredclosestringrequired
blockedCallersstring[]forwardCallerIdstring
smsobjectrequiredsms
enabledbooleanrequiredcapablebooleansendApprovedbooleanTexts deliver (US numbers need a carrier registration first).
domesticOnlybooleanCan only text numbers of its own country.
regulatoryobjectregulatory
declineReasonstringreviewCommentstringactionRequiredbooleanrequiredidVerificationUrlstringIdentity check for the registrant, once the order is placed (some countries).
createdAtstring (date-time)activatedAtstring (date-time)smsNoticestringAfter turning SMS on, what else it needs.
curl -X PUT "https://api.marsial.dev/v1/phone-numbers/num_…/sms" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": true }'const res = await fetch('https://api.marsial.dev/v1/phone-numbers/num_…/sms', { method: 'PUT', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "enabled": true }),});const { data } = await res.json();import os, requests
res = requests.put( "https://api.marsial.dev/v1/phone-numbers/num_…/sms", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "enabled": True },)data = res.json()["data"]© 2026 Marsial by TWOFACES ·marsial.dev ·Dashboard ·soporte@twofacesco.com