Skip to content

Mark a lead as contacted (partner-api)

Records that you emailed or called the lead. A lead in status new becomes contacted (and contacted_at is set); a lead in any other status is returned unchanged. Always answers 200 with the lead as it stands.

Required scopes: partner-api and partner-leads-write.

HTTP: PartnerApiKey

Partner API key. A bearer token that a Reseller Admin generates in the partner portal under Settings, API keys. It belongs to the reseller partner, not to a person, and carries the scopes ticked at creation time. Send it on every request as Authorization: Bearer <partner_api_key>.

Every response is confined to the partner the key belongs to. Keep the key secret and call the API from your server only, never from a browser app.

HTTP Authorization Scheme
bearer
Bearer format
Bearer <partner_api_key>
lead path · string · uuid *
Lead id (UUID). It must belong to your partner, otherwise the answer is `404`.
accept header · string
example: application/json

Request body · required · application/json

Request schema
channel*string
How you reached out.
enum: email call

Responses

Response schema
dataobject
A lead of the partner that owns the API key: somebody who left an address on your signup link from a country the self-signup funnel does not serve. The dedupe key, signup IP and browser are not exposed.
idstring · uuid
Unique identifier of the lead.
example: 550e8400-e29b-41d4-a716-446655440101
emailstring · email
The address the lead left.
example: prospect@example.com
country_isostring
ISO 3166-1 alpha-2 code of the lead's country (`ZZ` when unknown).
example: CH
localestring | null
Language the lead used on the signup page.
example: fr
plan_idstring | null · uuid
The plan the lead wanted, when known. Cleared if that plan is later deleted.
example: 550e8400-e29b-41d4-a716-446655440201
plan_namestring | null
Name of that plan when the lead arrived (a snapshot, kept if the plan is renamed).
example: Business Trial
statusstring
Follow-up status. `converted` is set only by the convert action.
enum: new contacted qualified converted lost
example: new
sourcestring | null
Where the lead came from, when recorded.
notesstring | null
Free-text notes kept by your team.
example: Asked for a callback on Monday.
contacted_atstring | null · date-time
When the lead was first marked contacted.
odoo_syncedboolean
True when the lead has a matching `crm.lead` in your Odoo.
example:
created_atstring · date-time
When the lead arrived.
example: 2026-10-28T09:12:00+00:00
updated_atstring · date-time
When the lead was last updated.
example: 2026-10-29T14:05:00+00:00
Unauthenticated. The `Authorization: Bearer <token>` header was missing, malformed, or names a token that has been revoked or deleted.
Response schema
messagestring
Forbidden. Three different situations share this status, told apart by `message`: * the token is not a partner API key (a user token, a PBX API key, or any other token); * the partner is not an active reseller; * the key lacks a scope the endpoint needs. The body then also lists `required_scopes`.
Response schema
messagestring
Human-readable reason.
example: This API key is missing a required scope.
required_scopesarray<string>
Present on the missing-scope 403 only. Scopes the endpoint needs that the key lacks.
[]string
Not Found. No lead with this id belongs to your partner (a lead of another partner, a nonexistent id and an id that is not a UUID answer the same way), or the signup funnel is switched off for the platform, in which case every leads endpoint answers `404`.
Response schema
messagestring
Human-readable reason.
example: This API key is missing a required scope.
required_scopesarray<string>
Present on the missing-scope 403 only. Scopes the endpoint needs that the key lacks.
[]string
Unprocessable Content. Either the body failed validation (`errors` keyed by field), or the lead is already a customer (`message` only): a converted lead can no longer change status or be converted again. Nothing was changed.
Response schema
messagestring
The first validation error, or the reason the action was refused.
errorsobject
Validation errors keyed by field. Absent when the action itself was refused.
Free-form object
Too Many Requests. Two budgets apply: 120 requests per minute per API key, and 600 per minute across all of a partner's keys together. Wait for the number of seconds in the `Retry-After` header before retrying.
Response schema
messagestring
post https://cockpit.voxbi.com/api/v1/api/v1/leads/{lead}/contacted
Base URL
Request sample
curl -X POST 'https://cockpit.voxbi.com/api/v1/api/v1/leads/{lead}/contacted' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  --data '{"channel":"call"}'
const response = await fetch('https://cockpit.voxbi.com/api/v1/api/v1/leads/{lead}/contacted', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${YOUR_TOKEN}`,
  },
  body: JSON.stringify({
    "channel": "call"
}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post('https://cockpit.voxbi.com/api/v1/api/v1/leads/{lead}/contacted',
    headers={'Authorization': f'Bearer {YOUR_TOKEN}'},
    json={
    "channel": "call"
}
)
response.raise_for_status()
data = response.json()
print(data)
<?php
$context = stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => "Content-Type: application/json\r\nAuthorization: Bearer YOUR_TOKEN",
        'content' => '{
    \"channel\": \"call\"
}',
    ],
]);

$response = file_get_contents('https://cockpit.voxbi.com/api/v1/api/v1/leads/{lead}/contacted', false, $context);
$data = json_decode($response, true);
print_r($data);
Sample request
{ … }
"channel": "call"
}
{ … }
"data": { … }
"id": "550e8400-e29b-41d4-a716-446655440101",
"email": "prospect@example.com",
"country_iso": "CH",
"locale": "fr",
"plan_id": "550e8400-e29b-41d4-a716-446655440201",
"plan_name": "Business Trial",
"status": "contacted",
"source": null,
"notes": null,
"contacted_at": "2026-11-03T08:30:00+00:00",
"odoo_synced": false,
"created_at": "2026-10-28T09:12:00+00:00",
"updated_at": "2026-10-29T14:05:00+00:00"
}
}
{ … }
"message": "Unauthenticated."
}
Content-Type string
example: application/json
{ … }
"message": "This endpoint requires a partner API key."
}
Content-Type string
example: application/json
{ … }
"message": "Lead not found."
}
Content-Type string
example: application/json
{ … }
"message": "The selected status is invalid.",
"errors": { … }
"status": [ … ]
"The selected status is invalid."
]
}
}
Content-Type string
example: application/json
{ … }
"message": "Too Many Attempts."
}
Retry-After integer
Seconds to wait before retrying.
example: 30
Content-Type string
example: application/json