/*
* Zernio API
*
* API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
*
* The version of the OpenAPI document: 1.0.4
* Contact: support@zernio.com
* Generated by: https://openapi-generator.tech
*/
use super::{configuration, ContentType, Error};
use crate::{apis::ResponseContent, models};
use reqwest;
use serde::{de::Error as _, Deserialize, Serialize};
use tokio::fs::File as TokioFile;
use tokio_util::codec::{BytesCodec, FramedRead};
/// struct for typed errors of method [`check_whats_app_number_availability`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CheckWhatsAppNumberAvailabilityError {
Status400(),
Status401(models::InlineObject),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`create_whats_app_number_kyc_link`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CreateWhatsAppNumberKycLinkError {
Status400(),
Status401(models::InlineObject),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_whats_app_number_info`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetWhatsAppNumberInfoError {
Status400(),
Status401(models::InlineObject),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_whats_app_number_kyc_form`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetWhatsAppNumberKycFormError {
Status400(),
Status401(models::InlineObject),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_whats_app_number_remediation`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetWhatsAppNumberRemediationError {
Status400(),
Status401(models::InlineObject),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_whats_app_phone_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetWhatsAppPhoneNumberError {
Status401(models::InlineObject),
Status404(models::InlineObject1),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_whats_app_phone_numbers`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetWhatsAppPhoneNumbersError {
Status401(models::InlineObject),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`list_whats_app_number_countries`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListWhatsAppNumberCountriesError {
Status401(models::InlineObject),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`purchase_whats_app_phone_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PurchaseWhatsAppPhoneNumberError {
Status400(),
Status401(models::InlineObject),
Status403(),
Status409(models::PurchasePhoneNumber409Response),
Status402(),
Status422(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`release_whats_app_phone_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ReleaseWhatsAppPhoneNumberError {
Status400(),
Status401(models::InlineObject),
Status404(models::InlineObject1),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`remediate_whats_app_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum RemediateWhatsAppNumberError {
Status400(),
Status401(models::InlineObject),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`search_available_whats_app_numbers`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SearchAvailableWhatsAppNumbersError {
Status400(),
Status401(models::InlineObject),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`submit_whats_app_number_kyc`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SubmitWhatsAppNumberKycError {
Status400(),
Status409(),
Status401(models::InlineObject),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`upload_whats_app_number_kyc_document`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UploadWhatsAppNumberKycDocumentError {
Status400(),
Status401(models::InlineObject),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`validate_whats_app_number_kyc_address`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ValidateWhatsAppNumberKycAddressError {
Status400(models::ValidatePhoneNumberKycAddress400Response),
Status401(models::InlineObject),
UnknownValue(serde_json::Value),
}
/// Deprecated alias of `/v1/phone-numbers/availability`; same contract. New integrations should use that path. Pre-purchase check, so you can warn BEFORE a customer invests in KYC (regulated review is async, 1-3 days). Tells you whether we have deliverable inventory, and what address the customer needs: - `addressConstraint: geo` → the registered address MUST be in one of the returned `areas` (the only place we have stock). A different-area address passes pre-approval but the number can never be assigned. - `addressConstraint: country` → any in-country address works. - `addressConstraint: none` → field-only / instant country, no address. Call this before starting the KYC form for regulated countries.
#[deprecated]
pub async fn check_whats_app_number_availability(
configuration: &configuration::Configuration,
country: &str,
) -> Result<
models::CheckPhoneNumberAvailability200Response,
Error<CheckWhatsAppNumberAvailabilityError>,
> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_country = country;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/availability",
configuration.base_path
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("country", &p_query_country.to_string())]);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::CheckPhoneNumberAvailability200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::CheckPhoneNumberAvailability200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<CheckWhatsAppNumberAvailabilityError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/kyc/share`; same contract. New integrations should use that path. Create a single-use, 7-day hosted KYC link that your end customer completes WITHOUT a Zernio login — useful when the person who holds the ID and address is not your team. They fill the regulated verification on a Zernio-hosted page; the number provisions under YOUR account once they submit. Only regulated (KYC) countries are valid: a country that does not require KYC returns 400. White-label the page with `branding` (your company name, logo, brand color). Supply `redirect_url` to send the end customer back to your own site after a successful submit (completion params are appended — see below). Listen for the `whatsapp.number.kyc_submitted` webhook to react when the form is completed.
#[deprecated]
pub async fn create_whats_app_number_kyc_link(
configuration: &configuration::Configuration,
create_phone_number_kyc_link_request: models::CreatePhoneNumberKycLinkRequest,
) -> Result<models::CreatePhoneNumberKycLink200Response, Error<CreateWhatsAppNumberKycLinkError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_create_phone_number_kyc_link_request = create_phone_number_kyc_link_request;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/kyc/share",
configuration.base_path
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_create_phone_number_kyc_link_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::CreatePhoneNumberKycLink200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::CreatePhoneNumberKycLink200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<CreateWhatsAppNumberKycLinkError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Live snapshot of a connected number straight from Meta: the phone-number node (display number, display name + approval, quality rating, messaging-limit tier, throughput, official-business badge, connection status, health_status) and its owning WhatsApp Business Account (name, business verification, timezone, health_status). Fetched live because Meta updates quality/tier/name/health over time; the call also refreshes the cached values shown on the connection card.
pub async fn get_whats_app_number_info(
configuration: &configuration::Configuration,
account_id: &str,
) -> Result<models::GetWhatsAppNumberInfo200Response, Error<GetWhatsAppNumberInfoError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_account_id = account_id;
let uri_str = format!("{}/v1/whatsapp/number-info", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("accountId", &p_query_account_id.to_string())]);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetWhatsAppNumberInfo200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetWhatsAppNumberInfo200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetWhatsAppNumberInfoError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/kyc`; same contract. New integrations should use that path. For a Tier 3/4 country, the fields the end customer must provide (Telnyx regulatory requirements) before a number can be ordered: text, date, address, or file (document) per requirement.
#[deprecated]
pub async fn get_whats_app_number_kyc_form(
configuration: &configuration::Configuration,
country: &str,
profile_id: &str,
) -> Result<models::GetWhatsAppNumberKycForm200Response, Error<GetWhatsAppNumberKycFormError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_country = country;
let p_query_profile_id = profile_id;
let uri_str = format!("{}/v1/whatsapp/phone-numbers/kyc", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("country", &p_query_country.to_string())]);
req_builder = req_builder.query(&[("profileId", &p_query_profile_id.to_string())]);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetWhatsAppNumberKycForm200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetWhatsAppNumberKycForm200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetWhatsAppNumberKycFormError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/{id}/remediate`; same contract. New integrations should use that path. For a number in `regulatory_declined`, returns ONLY the requirements the reviewer flagged declined, as a form spec (same shape as the KYC form GET). The customer fixes just those — Telnyx supports correcting a declined requirement group and re-submitting it (no new number/group). Falls back to the full spec if the provider exposes no per-requirement flags.
#[deprecated]
pub async fn get_whats_app_number_remediation(
configuration: &configuration::Configuration,
id: &str,
) -> Result<models::GetWhatsAppNumberRemediation200Response, Error<GetWhatsAppNumberRemediationError>>
{
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/{id}/remediate",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetWhatsAppNumberRemediation200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetWhatsAppNumberRemediation200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetWhatsAppNumberRemediationError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/{id}`; same contract. New integrations should use that path. Retrieve the current status of a purchased phone number. Poll this to track Meta pre-verification (US sync path) and, for regulated (Tier 3/4) numbers, the async lifecycle: pending_regulatory → active (or regulatory_declined). When a regulated number has an Onfido ID step, `onfidoVerificationUrl` appears here once the order is placed — forward it to the end user. (Or subscribe to the whatsapp.number.* webhooks instead of polling.)
#[deprecated]
pub async fn get_whats_app_phone_number(
configuration: &configuration::Configuration,
phone_number_id: &str,
) -> Result<models::GetPhoneNumber200Response, Error<GetWhatsAppPhoneNumberError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_phone_number_id = phone_number_id;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/{phoneNumberId}",
configuration.base_path,
phoneNumberId = crate::apis::urlencode(p_path_phone_number_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetPhoneNumber200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetPhoneNumber200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetWhatsAppPhoneNumberError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers`; same contract. New integrations should use that path. List all WhatsApp phone numbers purchased by the authenticated user. By default, released numbers are excluded. Connected (bring-your-own) numbers are returned in the separate `connected` array — they are not billed and have no provisioning lifecycle.
#[deprecated]
pub async fn get_whats_app_phone_numbers(
configuration: &configuration::Configuration,
status: Option<&str>,
profile_id: Option<&str>,
) -> Result<models::ListPhoneNumbers200Response, Error<GetWhatsAppPhoneNumbersError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_status = status;
let p_query_profile_id = profile_id;
let uri_str = format!("{}/v1/whatsapp/phone-numbers", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_status {
req_builder = req_builder.query(&[("status", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_profile_id {
req_builder = req_builder.query(&[("profileId", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListPhoneNumbers200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListPhoneNumbers200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetWhatsAppPhoneNumbersError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/countries`; same contract. New integrations should use that path. The WhatsApp number countries available to purchase, each with its flat monthly price (cents), regulatory tier, whether it needs end-user KYC (Tier 3/4), and whether outbound calling is available (not BIC-blocked). Drives the country picker. Tier-4 countries appear only when enabled.
#[deprecated]
pub async fn list_whats_app_number_countries(
configuration: &configuration::Configuration,
) -> Result<models::ListWhatsAppNumberCountries200Response, Error<ListWhatsAppNumberCountriesError>>
{
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/countries",
configuration.base_path
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListWhatsAppNumberCountries200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListWhatsAppNumberCountries200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ListWhatsAppNumberCountriesError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/purchase`; same contract. New integrations should use that path. Initiate purchasing a WhatsApp phone number. Payment-first flow: the user does not pick a specific number. The system either creates a Stripe Checkout Session (first number) or increments the existing subscription quantity and provisions inline (subsequent numbers). Requires a paid plan. The maximum number of phone numbers is determined by the user's plan.
#[deprecated]
pub async fn purchase_whats_app_phone_number(
configuration: &configuration::Configuration,
purchase_whats_app_phone_number_request: models::PurchaseWhatsAppPhoneNumberRequest,
) -> Result<models::PurchasePhoneNumber200Response, Error<PurchaseWhatsAppPhoneNumberError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_purchase_whats_app_phone_number_request = purchase_whats_app_phone_number_request;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/purchase",
configuration.base_path
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_purchase_whats_app_phone_number_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PurchasePhoneNumber200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PurchasePhoneNumber200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<PurchaseWhatsAppPhoneNumberError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/{id}`; same contract. New integrations should use that path. Release a purchased phone number. This will: 1. Disconnect any linked WhatsApp social account 2. Decrement the Stripe subscription quantity (or cancel if last number) 3. Release the number from Telnyx 4. Mark the number as released
#[deprecated]
pub async fn release_whats_app_phone_number(
configuration: &configuration::Configuration,
phone_number_id: &str,
) -> Result<models::ReleasePhoneNumber200Response, Error<ReleaseWhatsAppPhoneNumberError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_phone_number_id = phone_number_id;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/{phoneNumberId}",
configuration.base_path,
phoneNumberId = crate::apis::urlencode(p_path_phone_number_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::DELETE, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ReleasePhoneNumber200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ReleasePhoneNumber200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ReleaseWhatsAppPhoneNumberError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/{id}/remediate`; same contract. New integrations should use that path. Submit corrected values/documents for the declined requirement(s). We PATCH them onto the SAME requirement group and re-submit it for approval; the number goes `regulatory_declined` → `pending_regulatory`. No new number and no new billing. Body shape matches the KYC submit (values / documents / address) — send only the corrected fields.
#[deprecated]
pub async fn remediate_whats_app_number(
configuration: &configuration::Configuration,
id: &str,
remediate_phone_number_request: models::RemediatePhoneNumberRequest,
) -> Result<models::RemediatePhoneNumber200Response, Error<RemediateWhatsAppNumberError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_id = id;
let p_body_remediate_phone_number_request = remediate_phone_number_request;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/{id}/remediate",
configuration.base_path,
id = crate::apis::urlencode(p_path_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_remediate_phone_number_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::RemediatePhoneNumber200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::RemediatePhoneNumber200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<RemediateWhatsAppNumberError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/available`; same contract. New integrations should use that path. Search the provider's inventory for numbers available to purchase in a country (default US). Optional filters narrow the results. The country must be offerable (see GET /v1/whatsapp/phone-numbers/countries).
#[deprecated]
pub async fn search_available_whats_app_numbers(
configuration: &configuration::Configuration,
country: Option<&str>,
r#type: Option<&str>,
prefix: Option<&str>,
locality: Option<&str>,
contains: Option<&str>,
limit: Option<i32>,
) -> Result<
models::SearchAvailableWhatsAppNumbers200Response,
Error<SearchAvailableWhatsAppNumbersError>,
> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_country = country;
let p_query_type = r#type;
let p_query_prefix = prefix;
let p_query_locality = locality;
let p_query_contains = contains;
let p_query_limit = limit;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/available",
configuration.base_path
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_country {
req_builder = req_builder.query(&[("country", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_type {
req_builder = req_builder.query(&[("type", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_prefix {
req_builder = req_builder.query(&[("prefix", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_locality {
req_builder = req_builder.query(&[("locality", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_contains {
req_builder = req_builder.query(&[("contains", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_limit {
req_builder = req_builder.query(&[("limit", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SearchAvailableWhatsAppNumbers200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SearchAvailableWhatsAppNumbers200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<SearchAvailableWhatsAppNumbersError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/kyc`; same contract. New integrations should use that path. Submit the end customer's KYC (textual values, uploaded documents, address) for a Tier 3/4 country. Documents are streamed straight to the number provider and are not stored by Zernio. Builds + submits a regulatory requirement group and claims a pending_regulatory slot; the number is ordered + activated once the provider approves (asynchronous). A customer may hold several same-country numbers in review at once; a double-submit of the SAME attempt is deduped via `submissionId`. For an ID-card document requirement, carriers commonly require BOTH sides: combine the front and back into a single file before uploading (the dashboard does this automatically). A one-sided ID is a common decline reason; fix it via POST /v1/whatsapp/phone-numbers/{id}/remediate. Before submitting, call GET /v1/whatsapp/phone-numbers/availability to check the country has deliverable inventory and, for geographic-match countries, which area the address must be in — otherwise the submission can pass review yet never be assignable a number.
#[deprecated]
pub async fn submit_whats_app_number_kyc(
configuration: &configuration::Configuration,
submit_whats_app_number_kyc_request: models::SubmitWhatsAppNumberKycRequest,
) -> Result<models::SubmitPhoneNumberKyc200Response, Error<SubmitWhatsAppNumberKycError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_submit_whats_app_number_kyc_request = submit_whats_app_number_kyc_request;
let uri_str = format!("{}/v1/whatsapp/phone-numbers/kyc", configuration.base_path);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_submit_whats_app_number_kyc_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SubmitPhoneNumberKyc200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SubmitPhoneNumberKyc200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<SubmitWhatsAppNumberKycError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/kyc/upload-document`; same contract. New integrations should use that path. Upload ONE document and get back its provider document id, to reference from POST /v1/whatsapp/phone-numbers/kyc via `documents[].documentId`. Send the RAW file bytes as the request body (not base64); put the filename in the `X-Filename` header. Uploading documents one-per-request keeps each request under the ~4.5MB body limit. The document streams straight to the number provider and is not stored by Zernio.
#[deprecated]
pub async fn upload_whats_app_number_kyc_document(
configuration: &configuration::Configuration,
x_filename: &str,
body: std::path::PathBuf,
) -> Result<
models::UploadPhoneNumberKycDocument200Response,
Error<UploadWhatsAppNumberKycDocumentError>,
> {
// add a prefix to parameters to efficiently prevent name collisions
let p_header_x_filename = x_filename;
let p_body_body = body;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/kyc/upload-document",
configuration.base_path
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
req_builder = req_builder.header("X-Filename", p_header_x_filename.to_string());
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let file = TokioFile::open(p_body_body).await?;
let stream = FramedRead::new(file, BytesCodec::new());
req_builder = req_builder.body(reqwest::Body::wrap_stream(stream));
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UploadPhoneNumberKycDocument200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UploadPhoneNumberKycDocument200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UploadWhatsAppNumberKycDocumentError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Deprecated alias of `/v1/phone-numbers/kyc/validate-address`; same contract. New integrations should use that path. Optional early check for the address step of a Tier 4 (end-user identity) registration: validates a postal address for deliverability BEFORE the full KYC submit, so it can be corrected before any documents are uploaded. The full submit (POST /v1/whatsapp/phone-numbers/kyc) re-validates the address, so this call is purely a fast feedback path and skipping it is safe. Only the postal address is sent (no documents, no gov-ID fields). A region (`administrative_area`) is required by the validator; when it is omitted the pre-check is skipped and `{ ok: true, skipped: true }` is returned (the final submit still validates).
#[deprecated]
pub async fn validate_whats_app_number_kyc_address(
configuration: &configuration::Configuration,
validate_phone_number_kyc_address_request: models::ValidatePhoneNumberKycAddressRequest,
) -> Result<
models::ValidatePhoneNumberKycAddress200Response,
Error<ValidateWhatsAppNumberKycAddressError>,
> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_validate_phone_number_kyc_address_request =
validate_phone_number_kyc_address_request;
let uri_str = format!(
"{}/v1/whatsapp/phone-numbers/kyc/validate-address",
configuration.base_path
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_validate_phone_number_kyc_address_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ValidatePhoneNumberKycAddress200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ValidatePhoneNumberKycAddress200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ValidateWhatsAppNumberKycAddressError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}