> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.talkif.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.talkif.ai/_mcp/server.

# Create WebRTC test call

POST https://api.talkif.ai/api/v1/calls/webrtc/test
Content-Type: application/json

Starts a browser call that runs the flow definition sent in the request
instead of the published version, so changes can be tried before
publishing. The definition is validated first. The call is recorded with
version `draft` and billed like any other call.

Reference: https://docs.talkif.ai/api-reference/calls/create-webrtc-test-call

## Authentication

- `Authorization` header (bearer token, required) — Pass a JWT access token or an API key (prefixed with `tif_live_`) as a Bearer token.

## Request

### Body (application/json)

This endpoint expects a CreateWebRTCTestCallRequest.

- `definition` (FlowDefinition, required) — Flow definition to run instead of the published version
- `flowId` (string, required) — Flow ID to test with a draft definition
- `metadata` (CreateWebRtcTestCallRequestMetadata, optional, nullable) — Additional metadata to attach to the call

## Response

### 201

WebRTC test call created

- `callId` (string, required) — Unique call identifier
- `flowId` (string, required) — Flow ID used for the AI conversation
- `status` (enum, required) — Current call status
  - Allowed values: `queued`, `initiated`, `ringing`, `inprogress`, `completed`, `failed`, `busy`, `noanswer`, `canceled`
- `botId` (string, optional, nullable) — Identifier of the agent instance serving the call, if one is assigned yet
- `offerDeadlineAt` (string, optional, nullable) — The agent waits for your SDP offer until this time (RFC 3339), then releases itself and the call can no longer start. Send the offer well before it: connecting still takes a few seconds after the offer. Absent when no agent is assigned or the agent did not report its window.

## Errors

### 400 Bad Request Error

`validation_failed`, `bad_request`

- `code` (enum, required) — Machine-readable error code for programmatic handling
  - Allowed values: `invalid_credentials`, `email_already_exists`, `phone_already_exists`, `contact_phone_already_exists`, `account_suspended`, `account_pending_deletion`, `login_pending_deletion`, `owns_organization_with_members`, `account_deletion_blocked`, `client_update_required`, `account_access_denied`, `token_expired`, `token_invalid`, `token_missing`, `account_header_missing`, `refresh_token_invalid`, `email_already_verified`, `email_verification_code_invalid`, `email_verification_code_expired`, `email_verification_code_used`, `email_service_unavailable`, `phone_already_verified`, `phone_verification_code_invalid`, `bot_check_failed`, `phone_verification_code_expired`, `phone_verification_code_used`, `phone_number_missing`, `email_not_verified`, `disposable_email_not_allowed`, `request_blocked`, `phone_verification_refused`, `sms_service_unavailable`, `mfa_already_enabled`, `mfa_not_enabled`, `mfa_not_setup`, `mfa_code_invalid`, `passkey_not_found`, `password_reset_token_invalid`, `password_reset_token_expired`, `password_reset_token_used`, `password_current_incorrect`, `password_same_as_current`, `invalid_o_auth_state`, `o_auth_provider_error`, `o_auth_already_linked`, `provider_already_connected`, `o_auth_not_linked`, `cannot_unlink_only_auth`, `validation_failed`, `bad_request`, `ring_target_required`, `invalid_json`, `resource_not_found`, `not_found`, `forbidden`, `insufficient_permissions`, `connectors_consent_required`, `already_answered`, `expired`, `conflict`, `resource_already_exists`, `insufficient_balance`, `payment_required`, `subscription_required`, `feature_not_available`, `payment_failed`, `business_rule_violation`, `invalid_state_transition`, `unprocessable_entity`, `rate_limit_exceeded`, `queue_full`, `assistant_quota_exceeded`, `phone_purchase_rate_limited`, `user_phone_not_verified`, `account_not_verified`, `owner_verification_required`, `payment_method_required`, `trial_already_claimed`, `promotion_not_eligible`, `coupon_not_found`, `coupon_not_redeemable`, `coupon_already_redeemed`, `phone_number_not_active`, `phone_number_not_verified`, `phone_number_cannot_initiate_calls`, `flow_not_published`, `provider_call_rejected`, `concurrent_call_limit_exceeded`, `daily_call_limit_exceeded`, `contact_on_dnc_list`, `outside_callable_hours`, `call_already_completed`, `phone_provider_not_active`, `phone_number_already_connected`, `phone_number_not_connected`, `provider_must_be_sip`, `verification_only_for_sip`, `phone_verification_not_started`, `twilio_credentials_required`, `byoc_only`, `phone_already_registered`, `cannot_delete_system_provider`, `phone_number_type_unavailable`, `flow_name_already_exists`, `flow_structure_invalid`, `flow_has_connected_phones`, `flow_version_invalid`, `flow_version_conflict`, `flow_function_name_exists`, `flow_function_not_found`, `flow_generation_failed`, `payment_method_card_only`, `apple_transaction_invalid`, `apple_transaction_account_mismatch`, `sandbox_purchase_not_allowed`, `template_variable_resolution_failed`, `phone_number_in_use`, `phone_number_limit_reached`, `mfa_token_invalid`, `invalid_id_format`, `verification_code_invalid`, `cannot_delete_has_dependencies`, `in_use`, `unsupported_kind`, `offer_taken`, `offer_taken_self`, `offer_expired`, `already_taken`, `takeover_unsupported`, `schedule_not_found`, `schedule_already_paused`, `schedule_not_paused`, `invalid_cron_expression`, `invalid_timezone`, `campaign_not_found`, `campaign_not_draft`, `campaign_no_contacts`, `legal_acceptance_required`, `invitation_not_found`, `invitation_not_pending`, `invitation_expired`, `not_invitation_recipient`, `organization_suspended`, `already_organization_member`, `api_key_invalid`, `api_key_expired`, `api_key_revoked`, `api_key_not_allowed`, `api_key_insufficient_scope`, `api_key_ip_restricted`, `api_key_limit_reached`, `internal_error`, `service_error`, `service_unavailable`, `no_bots_available`, `region_saturated`, `recording_not_available`, `recording_service_not_configured`, `meta_not_configured`, `meta_page_already_connected`, `meta_form_already_mapped`, `meta_api_error`, `meta_lead_unrecoverable`, `unauthorized`
- `detail` (string, required) — Human-readable detail message for this specific error instance
- `status` (integer, required) — HTTP status code (mirrors the response status line)
- `title` (string, required) — Human-readable title for the error category
- `errors` (list of FieldError, optional, nullable) — Field-level validation errors, present when code is `validation_failed`
- `meta` (ErrorResponseMeta, optional, nullable) — Additional context metadata (e.g., retryAfterSecs for rate limits)
- `requestId` (string, optional, nullable) — Unique request identifier for debugging (also in X-Request-Id response header)

### 401 Unauthorized Error

Authentication required — token is missing, expired, or invalid

- `code` (enum, required) — Machine-readable error code for programmatic handling
  - Allowed values: `invalid_credentials`, `email_already_exists`, `phone_already_exists`, `contact_phone_already_exists`, `account_suspended`, `account_pending_deletion`, `login_pending_deletion`, `owns_organization_with_members`, `account_deletion_blocked`, `client_update_required`, `account_access_denied`, `token_expired`, `token_invalid`, `token_missing`, `account_header_missing`, `refresh_token_invalid`, `email_already_verified`, `email_verification_code_invalid`, `email_verification_code_expired`, `email_verification_code_used`, `email_service_unavailable`, `phone_already_verified`, `phone_verification_code_invalid`, `bot_check_failed`, `phone_verification_code_expired`, `phone_verification_code_used`, `phone_number_missing`, `email_not_verified`, `disposable_email_not_allowed`, `request_blocked`, `phone_verification_refused`, `sms_service_unavailable`, `mfa_already_enabled`, `mfa_not_enabled`, `mfa_not_setup`, `mfa_code_invalid`, `passkey_not_found`, `password_reset_token_invalid`, `password_reset_token_expired`, `password_reset_token_used`, `password_current_incorrect`, `password_same_as_current`, `invalid_o_auth_state`, `o_auth_provider_error`, `o_auth_already_linked`, `provider_already_connected`, `o_auth_not_linked`, `cannot_unlink_only_auth`, `validation_failed`, `bad_request`, `ring_target_required`, `invalid_json`, `resource_not_found`, `not_found`, `forbidden`, `insufficient_permissions`, `connectors_consent_required`, `already_answered`, `expired`, `conflict`, `resource_already_exists`, `insufficient_balance`, `payment_required`, `subscription_required`, `feature_not_available`, `payment_failed`, `business_rule_violation`, `invalid_state_transition`, `unprocessable_entity`, `rate_limit_exceeded`, `queue_full`, `assistant_quota_exceeded`, `phone_purchase_rate_limited`, `user_phone_not_verified`, `account_not_verified`, `owner_verification_required`, `payment_method_required`, `trial_already_claimed`, `promotion_not_eligible`, `coupon_not_found`, `coupon_not_redeemable`, `coupon_already_redeemed`, `phone_number_not_active`, `phone_number_not_verified`, `phone_number_cannot_initiate_calls`, `flow_not_published`, `provider_call_rejected`, `concurrent_call_limit_exceeded`, `daily_call_limit_exceeded`, `contact_on_dnc_list`, `outside_callable_hours`, `call_already_completed`, `phone_provider_not_active`, `phone_number_already_connected`, `phone_number_not_connected`, `provider_must_be_sip`, `verification_only_for_sip`, `phone_verification_not_started`, `twilio_credentials_required`, `byoc_only`, `phone_already_registered`, `cannot_delete_system_provider`, `phone_number_type_unavailable`, `flow_name_already_exists`, `flow_structure_invalid`, `flow_has_connected_phones`, `flow_version_invalid`, `flow_version_conflict`, `flow_function_name_exists`, `flow_function_not_found`, `flow_generation_failed`, `payment_method_card_only`, `apple_transaction_invalid`, `apple_transaction_account_mismatch`, `sandbox_purchase_not_allowed`, `template_variable_resolution_failed`, `phone_number_in_use`, `phone_number_limit_reached`, `mfa_token_invalid`, `invalid_id_format`, `verification_code_invalid`, `cannot_delete_has_dependencies`, `in_use`, `unsupported_kind`, `offer_taken`, `offer_taken_self`, `offer_expired`, `already_taken`, `takeover_unsupported`, `schedule_not_found`, `schedule_already_paused`, `schedule_not_paused`, `invalid_cron_expression`, `invalid_timezone`, `campaign_not_found`, `campaign_not_draft`, `campaign_no_contacts`, `legal_acceptance_required`, `invitation_not_found`, `invitation_not_pending`, `invitation_expired`, `not_invitation_recipient`, `organization_suspended`, `already_organization_member`, `api_key_invalid`, `api_key_expired`, `api_key_revoked`, `api_key_not_allowed`, `api_key_insufficient_scope`, `api_key_ip_restricted`, `api_key_limit_reached`, `internal_error`, `service_error`, `service_unavailable`, `no_bots_available`, `region_saturated`, `recording_not_available`, `recording_service_not_configured`, `meta_not_configured`, `meta_page_already_connected`, `meta_form_already_mapped`, `meta_api_error`, `meta_lead_unrecoverable`, `unauthorized`
- `detail` (string, required) — Human-readable detail message for this specific error instance
- `status` (integer, required) — HTTP status code (mirrors the response status line)
- `title` (string, required) — Human-readable title for the error category
- `errors` (list of FieldError, optional, nullable) — Field-level validation errors, present when code is `validation_failed`
- `meta` (ErrorResponseMeta, optional, nullable) — Additional context metadata (e.g., retryAfterSecs for rate limits)
- `requestId` (string, optional, nullable) — Unique request identifier for debugging (also in X-Request-Id response header)

### 403 Forbidden Error

`forbidden`

- `code` (enum, required) — Machine-readable error code for programmatic handling
  - Allowed values: `invalid_credentials`, `email_already_exists`, `phone_already_exists`, `contact_phone_already_exists`, `account_suspended`, `account_pending_deletion`, `login_pending_deletion`, `owns_organization_with_members`, `account_deletion_blocked`, `client_update_required`, `account_access_denied`, `token_expired`, `token_invalid`, `token_missing`, `account_header_missing`, `refresh_token_invalid`, `email_already_verified`, `email_verification_code_invalid`, `email_verification_code_expired`, `email_verification_code_used`, `email_service_unavailable`, `phone_already_verified`, `phone_verification_code_invalid`, `bot_check_failed`, `phone_verification_code_expired`, `phone_verification_code_used`, `phone_number_missing`, `email_not_verified`, `disposable_email_not_allowed`, `request_blocked`, `phone_verification_refused`, `sms_service_unavailable`, `mfa_already_enabled`, `mfa_not_enabled`, `mfa_not_setup`, `mfa_code_invalid`, `passkey_not_found`, `password_reset_token_invalid`, `password_reset_token_expired`, `password_reset_token_used`, `password_current_incorrect`, `password_same_as_current`, `invalid_o_auth_state`, `o_auth_provider_error`, `o_auth_already_linked`, `provider_already_connected`, `o_auth_not_linked`, `cannot_unlink_only_auth`, `validation_failed`, `bad_request`, `ring_target_required`, `invalid_json`, `resource_not_found`, `not_found`, `forbidden`, `insufficient_permissions`, `connectors_consent_required`, `already_answered`, `expired`, `conflict`, `resource_already_exists`, `insufficient_balance`, `payment_required`, `subscription_required`, `feature_not_available`, `payment_failed`, `business_rule_violation`, `invalid_state_transition`, `unprocessable_entity`, `rate_limit_exceeded`, `queue_full`, `assistant_quota_exceeded`, `phone_purchase_rate_limited`, `user_phone_not_verified`, `account_not_verified`, `owner_verification_required`, `payment_method_required`, `trial_already_claimed`, `promotion_not_eligible`, `coupon_not_found`, `coupon_not_redeemable`, `coupon_already_redeemed`, `phone_number_not_active`, `phone_number_not_verified`, `phone_number_cannot_initiate_calls`, `flow_not_published`, `provider_call_rejected`, `concurrent_call_limit_exceeded`, `daily_call_limit_exceeded`, `contact_on_dnc_list`, `outside_callable_hours`, `call_already_completed`, `phone_provider_not_active`, `phone_number_already_connected`, `phone_number_not_connected`, `provider_must_be_sip`, `verification_only_for_sip`, `phone_verification_not_started`, `twilio_credentials_required`, `byoc_only`, `phone_already_registered`, `cannot_delete_system_provider`, `phone_number_type_unavailable`, `flow_name_already_exists`, `flow_structure_invalid`, `flow_has_connected_phones`, `flow_version_invalid`, `flow_version_conflict`, `flow_function_name_exists`, `flow_function_not_found`, `flow_generation_failed`, `payment_method_card_only`, `apple_transaction_invalid`, `apple_transaction_account_mismatch`, `sandbox_purchase_not_allowed`, `template_variable_resolution_failed`, `phone_number_in_use`, `phone_number_limit_reached`, `mfa_token_invalid`, `invalid_id_format`, `verification_code_invalid`, `cannot_delete_has_dependencies`, `in_use`, `unsupported_kind`, `offer_taken`, `offer_taken_self`, `offer_expired`, `already_taken`, `takeover_unsupported`, `schedule_not_found`, `schedule_already_paused`, `schedule_not_paused`, `invalid_cron_expression`, `invalid_timezone`, `campaign_not_found`, `campaign_not_draft`, `campaign_no_contacts`, `legal_acceptance_required`, `invitation_not_found`, `invitation_not_pending`, `invitation_expired`, `not_invitation_recipient`, `organization_suspended`, `already_organization_member`, `api_key_invalid`, `api_key_expired`, `api_key_revoked`, `api_key_not_allowed`, `api_key_insufficient_scope`, `api_key_ip_restricted`, `api_key_limit_reached`, `internal_error`, `service_error`, `service_unavailable`, `no_bots_available`, `region_saturated`, `recording_not_available`, `recording_service_not_configured`, `meta_not_configured`, `meta_page_already_connected`, `meta_form_already_mapped`, `meta_api_error`, `meta_lead_unrecoverable`, `unauthorized`
- `detail` (string, required) — Human-readable detail message for this specific error instance
- `status` (integer, required) — HTTP status code (mirrors the response status line)
- `title` (string, required) — Human-readable title for the error category
- `errors` (list of FieldError, optional, nullable) — Field-level validation errors, present when code is `validation_failed`
- `meta` (ErrorResponseMeta, optional, nullable) — Additional context metadata (e.g., retryAfterSecs for rate limits)
- `requestId` (string, optional, nullable) — Unique request identifier for debugging (also in X-Request-Id response header)

### 404 Not Found Error

`resource_not_found`

- `code` (enum, required) — Machine-readable error code for programmatic handling
  - Allowed values: `invalid_credentials`, `email_already_exists`, `phone_already_exists`, `contact_phone_already_exists`, `account_suspended`, `account_pending_deletion`, `login_pending_deletion`, `owns_organization_with_members`, `account_deletion_blocked`, `client_update_required`, `account_access_denied`, `token_expired`, `token_invalid`, `token_missing`, `account_header_missing`, `refresh_token_invalid`, `email_already_verified`, `email_verification_code_invalid`, `email_verification_code_expired`, `email_verification_code_used`, `email_service_unavailable`, `phone_already_verified`, `phone_verification_code_invalid`, `bot_check_failed`, `phone_verification_code_expired`, `phone_verification_code_used`, `phone_number_missing`, `email_not_verified`, `disposable_email_not_allowed`, `request_blocked`, `phone_verification_refused`, `sms_service_unavailable`, `mfa_already_enabled`, `mfa_not_enabled`, `mfa_not_setup`, `mfa_code_invalid`, `passkey_not_found`, `password_reset_token_invalid`, `password_reset_token_expired`, `password_reset_token_used`, `password_current_incorrect`, `password_same_as_current`, `invalid_o_auth_state`, `o_auth_provider_error`, `o_auth_already_linked`, `provider_already_connected`, `o_auth_not_linked`, `cannot_unlink_only_auth`, `validation_failed`, `bad_request`, `ring_target_required`, `invalid_json`, `resource_not_found`, `not_found`, `forbidden`, `insufficient_permissions`, `connectors_consent_required`, `already_answered`, `expired`, `conflict`, `resource_already_exists`, `insufficient_balance`, `payment_required`, `subscription_required`, `feature_not_available`, `payment_failed`, `business_rule_violation`, `invalid_state_transition`, `unprocessable_entity`, `rate_limit_exceeded`, `queue_full`, `assistant_quota_exceeded`, `phone_purchase_rate_limited`, `user_phone_not_verified`, `account_not_verified`, `owner_verification_required`, `payment_method_required`, `trial_already_claimed`, `promotion_not_eligible`, `coupon_not_found`, `coupon_not_redeemable`, `coupon_already_redeemed`, `phone_number_not_active`, `phone_number_not_verified`, `phone_number_cannot_initiate_calls`, `flow_not_published`, `provider_call_rejected`, `concurrent_call_limit_exceeded`, `daily_call_limit_exceeded`, `contact_on_dnc_list`, `outside_callable_hours`, `call_already_completed`, `phone_provider_not_active`, `phone_number_already_connected`, `phone_number_not_connected`, `provider_must_be_sip`, `verification_only_for_sip`, `phone_verification_not_started`, `twilio_credentials_required`, `byoc_only`, `phone_already_registered`, `cannot_delete_system_provider`, `phone_number_type_unavailable`, `flow_name_already_exists`, `flow_structure_invalid`, `flow_has_connected_phones`, `flow_version_invalid`, `flow_version_conflict`, `flow_function_name_exists`, `flow_function_not_found`, `flow_generation_failed`, `payment_method_card_only`, `apple_transaction_invalid`, `apple_transaction_account_mismatch`, `sandbox_purchase_not_allowed`, `template_variable_resolution_failed`, `phone_number_in_use`, `phone_number_limit_reached`, `mfa_token_invalid`, `invalid_id_format`, `verification_code_invalid`, `cannot_delete_has_dependencies`, `in_use`, `unsupported_kind`, `offer_taken`, `offer_taken_self`, `offer_expired`, `already_taken`, `takeover_unsupported`, `schedule_not_found`, `schedule_already_paused`, `schedule_not_paused`, `invalid_cron_expression`, `invalid_timezone`, `campaign_not_found`, `campaign_not_draft`, `campaign_no_contacts`, `legal_acceptance_required`, `invitation_not_found`, `invitation_not_pending`, `invitation_expired`, `not_invitation_recipient`, `organization_suspended`, `already_organization_member`, `api_key_invalid`, `api_key_expired`, `api_key_revoked`, `api_key_not_allowed`, `api_key_insufficient_scope`, `api_key_ip_restricted`, `api_key_limit_reached`, `internal_error`, `service_error`, `service_unavailable`, `no_bots_available`, `region_saturated`, `recording_not_available`, `recording_service_not_configured`, `meta_not_configured`, `meta_page_already_connected`, `meta_form_already_mapped`, `meta_api_error`, `meta_lead_unrecoverable`, `unauthorized`
- `detail` (string, required) — Human-readable detail message for this specific error instance
- `status` (integer, required) — HTTP status code (mirrors the response status line)
- `title` (string, required) — Human-readable title for the error category
- `errors` (list of FieldError, optional, nullable) — Field-level validation errors, present when code is `validation_failed`
- `meta` (ErrorResponseMeta, optional, nullable) — Additional context metadata (e.g., retryAfterSecs for rate limits)
- `requestId` (string, optional, nullable) — Unique request identifier for debugging (also in X-Request-Id response header)

### 429 Too Many Requests Error

Rate limit exceeded — retry after the delay in the response

- `code` (enum, required) — Machine-readable error code for programmatic handling
  - Allowed values: `invalid_credentials`, `email_already_exists`, `phone_already_exists`, `contact_phone_already_exists`, `account_suspended`, `account_pending_deletion`, `login_pending_deletion`, `owns_organization_with_members`, `account_deletion_blocked`, `client_update_required`, `account_access_denied`, `token_expired`, `token_invalid`, `token_missing`, `account_header_missing`, `refresh_token_invalid`, `email_already_verified`, `email_verification_code_invalid`, `email_verification_code_expired`, `email_verification_code_used`, `email_service_unavailable`, `phone_already_verified`, `phone_verification_code_invalid`, `bot_check_failed`, `phone_verification_code_expired`, `phone_verification_code_used`, `phone_number_missing`, `email_not_verified`, `disposable_email_not_allowed`, `request_blocked`, `phone_verification_refused`, `sms_service_unavailable`, `mfa_already_enabled`, `mfa_not_enabled`, `mfa_not_setup`, `mfa_code_invalid`, `passkey_not_found`, `password_reset_token_invalid`, `password_reset_token_expired`, `password_reset_token_used`, `password_current_incorrect`, `password_same_as_current`, `invalid_o_auth_state`, `o_auth_provider_error`, `o_auth_already_linked`, `provider_already_connected`, `o_auth_not_linked`, `cannot_unlink_only_auth`, `validation_failed`, `bad_request`, `ring_target_required`, `invalid_json`, `resource_not_found`, `not_found`, `forbidden`, `insufficient_permissions`, `connectors_consent_required`, `already_answered`, `expired`, `conflict`, `resource_already_exists`, `insufficient_balance`, `payment_required`, `subscription_required`, `feature_not_available`, `payment_failed`, `business_rule_violation`, `invalid_state_transition`, `unprocessable_entity`, `rate_limit_exceeded`, `queue_full`, `assistant_quota_exceeded`, `phone_purchase_rate_limited`, `user_phone_not_verified`, `account_not_verified`, `owner_verification_required`, `payment_method_required`, `trial_already_claimed`, `promotion_not_eligible`, `coupon_not_found`, `coupon_not_redeemable`, `coupon_already_redeemed`, `phone_number_not_active`, `phone_number_not_verified`, `phone_number_cannot_initiate_calls`, `flow_not_published`, `provider_call_rejected`, `concurrent_call_limit_exceeded`, `daily_call_limit_exceeded`, `contact_on_dnc_list`, `outside_callable_hours`, `call_already_completed`, `phone_provider_not_active`, `phone_number_already_connected`, `phone_number_not_connected`, `provider_must_be_sip`, `verification_only_for_sip`, `phone_verification_not_started`, `twilio_credentials_required`, `byoc_only`, `phone_already_registered`, `cannot_delete_system_provider`, `phone_number_type_unavailable`, `flow_name_already_exists`, `flow_structure_invalid`, `flow_has_connected_phones`, `flow_version_invalid`, `flow_version_conflict`, `flow_function_name_exists`, `flow_function_not_found`, `flow_generation_failed`, `payment_method_card_only`, `apple_transaction_invalid`, `apple_transaction_account_mismatch`, `sandbox_purchase_not_allowed`, `template_variable_resolution_failed`, `phone_number_in_use`, `phone_number_limit_reached`, `mfa_token_invalid`, `invalid_id_format`, `verification_code_invalid`, `cannot_delete_has_dependencies`, `in_use`, `unsupported_kind`, `offer_taken`, `offer_taken_self`, `offer_expired`, `already_taken`, `takeover_unsupported`, `schedule_not_found`, `schedule_already_paused`, `schedule_not_paused`, `invalid_cron_expression`, `invalid_timezone`, `campaign_not_found`, `campaign_not_draft`, `campaign_no_contacts`, `legal_acceptance_required`, `invitation_not_found`, `invitation_not_pending`, `invitation_expired`, `not_invitation_recipient`, `organization_suspended`, `already_organization_member`, `api_key_invalid`, `api_key_expired`, `api_key_revoked`, `api_key_not_allowed`, `api_key_insufficient_scope`, `api_key_ip_restricted`, `api_key_limit_reached`, `internal_error`, `service_error`, `service_unavailable`, `no_bots_available`, `region_saturated`, `recording_not_available`, `recording_service_not_configured`, `meta_not_configured`, `meta_page_already_connected`, `meta_form_already_mapped`, `meta_api_error`, `meta_lead_unrecoverable`, `unauthorized`
- `detail` (string, required) — Human-readable detail message for this specific error instance
- `status` (integer, required) — HTTP status code (mirrors the response status line)
- `title` (string, required) — Human-readable title for the error category
- `errors` (list of FieldError, optional, nullable) — Field-level validation errors, present when code is `validation_failed`
- `meta` (ErrorResponseMeta, optional, nullable) — Additional context metadata (e.g., retryAfterSecs for rate limits)
- `requestId` (string, optional, nullable) — Unique request identifier for debugging (also in X-Request-Id response header)

### 500 Internal Server Error

Internal server error — contact support with the requestId

- `code` (enum, required) — Machine-readable error code for programmatic handling
  - Allowed values: `invalid_credentials`, `email_already_exists`, `phone_already_exists`, `contact_phone_already_exists`, `account_suspended`, `account_pending_deletion`, `login_pending_deletion`, `owns_organization_with_members`, `account_deletion_blocked`, `client_update_required`, `account_access_denied`, `token_expired`, `token_invalid`, `token_missing`, `account_header_missing`, `refresh_token_invalid`, `email_already_verified`, `email_verification_code_invalid`, `email_verification_code_expired`, `email_verification_code_used`, `email_service_unavailable`, `phone_already_verified`, `phone_verification_code_invalid`, `bot_check_failed`, `phone_verification_code_expired`, `phone_verification_code_used`, `phone_number_missing`, `email_not_verified`, `disposable_email_not_allowed`, `request_blocked`, `phone_verification_refused`, `sms_service_unavailable`, `mfa_already_enabled`, `mfa_not_enabled`, `mfa_not_setup`, `mfa_code_invalid`, `passkey_not_found`, `password_reset_token_invalid`, `password_reset_token_expired`, `password_reset_token_used`, `password_current_incorrect`, `password_same_as_current`, `invalid_o_auth_state`, `o_auth_provider_error`, `o_auth_already_linked`, `provider_already_connected`, `o_auth_not_linked`, `cannot_unlink_only_auth`, `validation_failed`, `bad_request`, `ring_target_required`, `invalid_json`, `resource_not_found`, `not_found`, `forbidden`, `insufficient_permissions`, `connectors_consent_required`, `already_answered`, `expired`, `conflict`, `resource_already_exists`, `insufficient_balance`, `payment_required`, `subscription_required`, `feature_not_available`, `payment_failed`, `business_rule_violation`, `invalid_state_transition`, `unprocessable_entity`, `rate_limit_exceeded`, `queue_full`, `assistant_quota_exceeded`, `phone_purchase_rate_limited`, `user_phone_not_verified`, `account_not_verified`, `owner_verification_required`, `payment_method_required`, `trial_already_claimed`, `promotion_not_eligible`, `coupon_not_found`, `coupon_not_redeemable`, `coupon_already_redeemed`, `phone_number_not_active`, `phone_number_not_verified`, `phone_number_cannot_initiate_calls`, `flow_not_published`, `provider_call_rejected`, `concurrent_call_limit_exceeded`, `daily_call_limit_exceeded`, `contact_on_dnc_list`, `outside_callable_hours`, `call_already_completed`, `phone_provider_not_active`, `phone_number_already_connected`, `phone_number_not_connected`, `provider_must_be_sip`, `verification_only_for_sip`, `phone_verification_not_started`, `twilio_credentials_required`, `byoc_only`, `phone_already_registered`, `cannot_delete_system_provider`, `phone_number_type_unavailable`, `flow_name_already_exists`, `flow_structure_invalid`, `flow_has_connected_phones`, `flow_version_invalid`, `flow_version_conflict`, `flow_function_name_exists`, `flow_function_not_found`, `flow_generation_failed`, `payment_method_card_only`, `apple_transaction_invalid`, `apple_transaction_account_mismatch`, `sandbox_purchase_not_allowed`, `template_variable_resolution_failed`, `phone_number_in_use`, `phone_number_limit_reached`, `mfa_token_invalid`, `invalid_id_format`, `verification_code_invalid`, `cannot_delete_has_dependencies`, `in_use`, `unsupported_kind`, `offer_taken`, `offer_taken_self`, `offer_expired`, `already_taken`, `takeover_unsupported`, `schedule_not_found`, `schedule_already_paused`, `schedule_not_paused`, `invalid_cron_expression`, `invalid_timezone`, `campaign_not_found`, `campaign_not_draft`, `campaign_no_contacts`, `legal_acceptance_required`, `invitation_not_found`, `invitation_not_pending`, `invitation_expired`, `not_invitation_recipient`, `organization_suspended`, `already_organization_member`, `api_key_invalid`, `api_key_expired`, `api_key_revoked`, `api_key_not_allowed`, `api_key_insufficient_scope`, `api_key_ip_restricted`, `api_key_limit_reached`, `internal_error`, `service_error`, `service_unavailable`, `no_bots_available`, `region_saturated`, `recording_not_available`, `recording_service_not_configured`, `meta_not_configured`, `meta_page_already_connected`, `meta_form_already_mapped`, `meta_api_error`, `meta_lead_unrecoverable`, `unauthorized`
- `detail` (string, required) — Human-readable detail message for this specific error instance
- `status` (integer, required) — HTTP status code (mirrors the response status line)
- `title` (string, required) — Human-readable title for the error category
- `errors` (list of FieldError, optional, nullable) — Field-level validation errors, present when code is `validation_failed`
- `meta` (ErrorResponseMeta, optional, nullable) — Additional context metadata (e.g., retryAfterSecs for rate limits)
- `requestId` (string, optional, nullable) — Unique request identifier for debugging (also in X-Request-Id response header)

### 503 Service Unavailable Error

`service_unavailable`

- `code` (enum, required) — Machine-readable error code for programmatic handling
  - Allowed values: `invalid_credentials`, `email_already_exists`, `phone_already_exists`, `contact_phone_already_exists`, `account_suspended`, `account_pending_deletion`, `login_pending_deletion`, `owns_organization_with_members`, `account_deletion_blocked`, `client_update_required`, `account_access_denied`, `token_expired`, `token_invalid`, `token_missing`, `account_header_missing`, `refresh_token_invalid`, `email_already_verified`, `email_verification_code_invalid`, `email_verification_code_expired`, `email_verification_code_used`, `email_service_unavailable`, `phone_already_verified`, `phone_verification_code_invalid`, `bot_check_failed`, `phone_verification_code_expired`, `phone_verification_code_used`, `phone_number_missing`, `email_not_verified`, `disposable_email_not_allowed`, `request_blocked`, `phone_verification_refused`, `sms_service_unavailable`, `mfa_already_enabled`, `mfa_not_enabled`, `mfa_not_setup`, `mfa_code_invalid`, `passkey_not_found`, `password_reset_token_invalid`, `password_reset_token_expired`, `password_reset_token_used`, `password_current_incorrect`, `password_same_as_current`, `invalid_o_auth_state`, `o_auth_provider_error`, `o_auth_already_linked`, `provider_already_connected`, `o_auth_not_linked`, `cannot_unlink_only_auth`, `validation_failed`, `bad_request`, `ring_target_required`, `invalid_json`, `resource_not_found`, `not_found`, `forbidden`, `insufficient_permissions`, `connectors_consent_required`, `already_answered`, `expired`, `conflict`, `resource_already_exists`, `insufficient_balance`, `payment_required`, `subscription_required`, `feature_not_available`, `payment_failed`, `business_rule_violation`, `invalid_state_transition`, `unprocessable_entity`, `rate_limit_exceeded`, `queue_full`, `assistant_quota_exceeded`, `phone_purchase_rate_limited`, `user_phone_not_verified`, `account_not_verified`, `owner_verification_required`, `payment_method_required`, `trial_already_claimed`, `promotion_not_eligible`, `coupon_not_found`, `coupon_not_redeemable`, `coupon_already_redeemed`, `phone_number_not_active`, `phone_number_not_verified`, `phone_number_cannot_initiate_calls`, `flow_not_published`, `provider_call_rejected`, `concurrent_call_limit_exceeded`, `daily_call_limit_exceeded`, `contact_on_dnc_list`, `outside_callable_hours`, `call_already_completed`, `phone_provider_not_active`, `phone_number_already_connected`, `phone_number_not_connected`, `provider_must_be_sip`, `verification_only_for_sip`, `phone_verification_not_started`, `twilio_credentials_required`, `byoc_only`, `phone_already_registered`, `cannot_delete_system_provider`, `phone_number_type_unavailable`, `flow_name_already_exists`, `flow_structure_invalid`, `flow_has_connected_phones`, `flow_version_invalid`, `flow_version_conflict`, `flow_function_name_exists`, `flow_function_not_found`, `flow_generation_failed`, `payment_method_card_only`, `apple_transaction_invalid`, `apple_transaction_account_mismatch`, `sandbox_purchase_not_allowed`, `template_variable_resolution_failed`, `phone_number_in_use`, `phone_number_limit_reached`, `mfa_token_invalid`, `invalid_id_format`, `verification_code_invalid`, `cannot_delete_has_dependencies`, `in_use`, `unsupported_kind`, `offer_taken`, `offer_taken_self`, `offer_expired`, `already_taken`, `takeover_unsupported`, `schedule_not_found`, `schedule_already_paused`, `schedule_not_paused`, `invalid_cron_expression`, `invalid_timezone`, `campaign_not_found`, `campaign_not_draft`, `campaign_no_contacts`, `legal_acceptance_required`, `invitation_not_found`, `invitation_not_pending`, `invitation_expired`, `not_invitation_recipient`, `organization_suspended`, `already_organization_member`, `api_key_invalid`, `api_key_expired`, `api_key_revoked`, `api_key_not_allowed`, `api_key_insufficient_scope`, `api_key_ip_restricted`, `api_key_limit_reached`, `internal_error`, `service_error`, `service_unavailable`, `no_bots_available`, `region_saturated`, `recording_not_available`, `recording_service_not_configured`, `meta_not_configured`, `meta_page_already_connected`, `meta_form_already_mapped`, `meta_api_error`, `meta_lead_unrecoverable`, `unauthorized`
- `detail` (string, required) — Human-readable detail message for this specific error instance
- `status` (integer, required) — HTTP status code (mirrors the response status line)
- `title` (string, required) — Human-readable title for the error category
- `errors` (list of FieldError, optional, nullable) — Field-level validation errors, present when code is `validation_failed`
- `meta` (ErrorResponseMeta, optional, nullable) — Additional context metadata (e.g., retryAfterSecs for rate limits)
- `requestId` (string, optional, nullable) — Unique request identifier for debugging (also in X-Request-Id response header)

## Types

### FlowDefinition

The canonical flow definition — single source of truth for flow logic, shared by the API and the visual builder. Visual nodes (LLM, TTS, STT, prompt, end_call) collapse into properties: - Service nodes -> `services.*` - Prompt nodes -> `agent.prompt` - Action nodes -> `agent.functions[]` - Edges are implicit — relationships expressed as data, not connections

- `initialNode` (string, required) — Node ID where execution begins (must reference a main_agent node)
- `nodes` (map from string to AgentDefinition, required) — Agent nodes keyed by node ID (e.g., "main_agent_1", "billing_agent")
- `services` (ServiceDefinition, required) — Service provider configuration (LLM, TTS, STT)

### CreateWebRtcTestCallRequestMetadata

Additional metadata to attach to the call

### FieldError

Individual field error for validation responses Appears in the `errors[]` array when `code` is `validation_failed` # Example ```json { "field": "email", "code": "invalid_format", "message": "Email format is invalid" } ```

- `code` (string, required) — Specific error code for this field
- `field` (string, required) — The field name that failed validation
- `message` (string, required) — Human-readable error message

### ErrorResponseMeta

Additional context metadata (e.g., retryAfterSecs for rate limits)

### AgentDefinition

Agent node definition Represents a conversational agent in the flow. The entry agent (`main_agent`) carries the call's `systemPrompt`; every agent carries its own `agentPrompt`. The system prompt is global to the call and persists across transitions, so non-entry agents must not set one (validation rejects it).

- `name` (string, required) — Display name
- `type` (enum, required) — Agent type: "main_agent" (exactly one, entry point) or "agent"
  - Allowed values: `main_agent`, `agent`
- `agentPrompt` (string, optional, nullable) — This agent's own instructions — THE canonical task field. In force only while the flow sits on this agent. Static and dynamic content share this one field: text containing `{{handlebars}}` is resolved at call time, plain text passes through. There is no prompt node, no edge, and no template indirection. `taskMessage` is accepted as a deprecated alias on input and stored as `agentPrompt`.
- `functions` (list of FunctionDefinition, optional) — Tool functions available to this agent (includes end_call, webhooks, etc.)
- `postActions` (list of ActionDefinition, optional) — Actions executed after agent finishes
- `preActions` (list of ActionDefinition, optional) — Actions executed before agent starts speaking
- `prompt` (PromptReference, optional, nullable) — Deprecated prompt wrapper, accepted for backwards compatibility. New definitions put the prompt inline in `AgentDefinition.agentPrompt`.
- `systemPrompt` (string, optional, nullable) — The call's system prompt — set on the entry agent only. Global to the call and persistent across agent transitions, so non-entry agents leave this `None` and inherit it. Validation rejects a `systemPrompt` on a non-entry agent. `roleMessage` is accepted as a deprecated alias on input and stored as `systemPrompt`.
- `transitions` (list of TransitionDefinition, optional) — Transitions to other agents (keywords trigger agent handoff)

### ServiceDefinition

Service provider configuration for LLM, TTS, and STT. All fields are optional during draft saves — a flow being built may not have all services configured yet. All three are required at publish time (enforced by `FlowDefinitionValidator`).

- `llm` (LLMServiceDefinition, optional, nullable) — LLM service configuration Supports: openai, anthropic, google, grok
- `stt` (STTServiceDefinition, optional, nullable) — STT service configuration Supports: deepgram, soniox, elevenlabs, cartesia. Use `language` for single-language providers, `languages` for Soniox multi-language.
- `tts` (TTSServiceDefinition, optional, nullable) — TTS service configuration Supports: elevenlabs, cartesia. Provider-specific fields are flattened — only relevant fields are set per provider.

### FunctionDefinition

JSON Schema for parameters the LLM extracts from conversation. For builtins: typically empty (no LLM params needed). For http_request: resolved from flow_functions DB record at publish time.

### ActionDefinition

Action definition for pre/post agent actions Actions execute before or after an agent speaks. Unlike functions (which are LLM-invoked tools), actions are deterministic steps triggered automatically by the flow engine. Action types: * `"tts_say"`: Speak specific text (config: `{ text: "..." }`) * `"play_audio"`: Play an audio file (config: `{ url: "..." }`) * `"wait"`: Pause for duration (config: `{ durationMs: 1000 }`) * `"webhook"`: Fire a webhook (config: `{ url: "...", method: "POST" }`)

- `type` (string, required) — Action type identifier
- `config` (ActionDefinitionConfig, optional, nullable) — Action-specific configuration (shape depends on action type)

### PromptReference

Deprecated prompt wrapper, accepted for backwards compatibility. New definitions put the prompt inline in `AgentDefinition.agentPrompt`.

- `content` (string, optional, nullable) — Inline content override (may contain \{\{handlebars}} expressions)
- `templateId` (string, optional, nullable) — Prompt template UUID (references prompt_templates table). Optional — omit for inline-only prompts that don't reference a saved template.

### TransitionDefinition

Agent transition definition Defines a handoff from one agent to another, triggered by keywords in the conversation. Exposed to the LLM as a tool at runtime.

- `targetAgentId` (string, required) — Target agent node ID
- `keywords` (string, optional) — Keywords/description that trigger this transition

### LLMServiceDefinition

LLM service configuration Supports: openai, anthropic, google, grok

- `model` (string, required) — Model identifier
- `provider` (string, required) — Provider identifier
- `endpoint` (string, optional, nullable) — Azure OpenAI deployment endpoint (required for Azure, omit for standard OpenAI)
- `label` (string, optional, nullable) — Display label for UI
- `maxTokens` (integer, optional, nullable) — Maximum tokens to generate
- `priorityTier` (boolean, optional, nullable) — OpenAI priority tier (2x cost, higher rate limits)
- `reasoningEffort` (string, optional, nullable) — Reasoning/thinking effort level. Only accepted by models that support reasoning, and only with a value that model lists as valid; anything else is ignored.
- `temperature` (double, optional, nullable) — Sampling temperature (0.0 - 2.0)

### STTServiceDefinition

STT service configuration Supports: deepgram, soniox, elevenlabs, cartesia. Use `language` for single-language providers, `languages` for Soniox multi-language.

- `model` (string, required) — Model identifier
- `provider` (string, required) — Provider identifier
- `keywords` (list of string, optional, nullable) — Keyword boosting terms
- `label` (string, optional, nullable) — Display label for UI
- `language` (string, optional, nullable) — Single language code (Deepgram, ElevenLabs, Cartesia, AssemblyAI, Whisper)
- `languages` (list of string, optional, nullable) — Language hints array for Soniox multi-language detection

### TTSServiceDefinition

TTS service configuration Supports: elevenlabs, cartesia. Provider-specific fields are flattened — only relevant fields are set per provider.

- `model` (string, required) — Model identifier
- `provider` (string, required) — Provider identifier
- `voiceId` (string, required) — Voice identifier
- `emotion` (string, optional, nullable) — Voice emotion preset (Cartesia Sonic v3)
- `label` (string, optional, nullable) — Display label for UI
- `language` (string, optional, nullable) — Voice language for localization (Cartesia)
- `similarity` (double, optional, nullable) — Voice similarity boost (0.0 - 1.0, ElevenLabs)
- `speakerBoost` (boolean, optional, nullable) — Speaker boost (ElevenLabs)
- `speed` (double, optional, nullable) — Speech speed multiplier (Cartesia Sonic v3)
- `stability` (double, optional, nullable) — Voice stability (0.0 - 1.0, ElevenLabs)
- `style` (double, optional, nullable) — Voice style (0.0 - 1.0, ElevenLabs)
- `voiceName` (string, optional, nullable) — Cached voice display name
- `volume` (double, optional, nullable) — Audio volume level (Cartesia Sonic v3)

### ActionDefinitionConfig

Action-specific configuration (shape depends on action type)

## Examples

**Request**

```json
{
  "definition": {
    "initialNode": "main_agent_1",
    "nodes": {},
    "services": {}
  },
  "flowId": "550e8400-e29b-41d4-a716-446655440000"
}
```

**Response**

```json
{
  "callId": "550e8400-e29b-41d4-a716-446655440000",
  "flowId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "queued",
  "botId": "bot-7f3a9c",
  "offerDeadlineAt": "2026-01-15T10:30:00Z"
}
```

**SDK Code**

```python
import requests

url = "https://api.talkif.ai/api/v1/calls/webrtc/test"

payload = {
    "definition": {
        "initialNode": "main_agent_1",
        "nodes": {},
        "services": {}
    },
    "flowId": "550e8400-e29b-41d4-a716-446655440000"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.talkif.ai/api/v1/calls/webrtc/test';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"definition":{"initialNode":"main_agent_1","nodes":{},"services":{}},"flowId":"550e8400-e29b-41d4-a716-446655440000"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.talkif.ai/api/v1/calls/webrtc/test"

	payload := strings.NewReader("{\n  \"definition\": {\n    \"initialNode\": \"main_agent_1\",\n    \"nodes\": {},\n    \"services\": {}\n  },\n  \"flowId\": \"550e8400-e29b-41d4-a716-446655440000\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.talkif.ai/api/v1/calls/webrtc/test")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"definition\": {\n    \"initialNode\": \"main_agent_1\",\n    \"nodes\": {},\n    \"services\": {}\n  },\n  \"flowId\": \"550e8400-e29b-41d4-a716-446655440000\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.talkif.ai/api/v1/calls/webrtc/test")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"definition\": {\n    \"initialNode\": \"main_agent_1\",\n    \"nodes\": {},\n    \"services\": {}\n  },\n  \"flowId\": \"550e8400-e29b-41d4-a716-446655440000\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.talkif.ai/api/v1/calls/webrtc/test', [
  'body' => '{
  "definition": {
    "initialNode": "main_agent_1",
    "nodes": {},
    "services": {}
  },
  "flowId": "550e8400-e29b-41d4-a716-446655440000"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.talkif.ai/api/v1/calls/webrtc/test");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"definition\": {\n    \"initialNode\": \"main_agent_1\",\n    \"nodes\": {},\n    \"services\": {}\n  },\n  \"flowId\": \"550e8400-e29b-41d4-a716-446655440000\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "definition": [
    "initialNode": "main_agent_1",
    "nodes": [],
    "services": []
  ],
  "flowId": "550e8400-e29b-41d4-a716-446655440000"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.talkif.ai/api/v1/calls/webrtc/test")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```