Quickstart

This walks you through sending a lead with a test key, then reading it back.

1. Create a test secret key

In your workspace, open Settings, API and integrations and choose New key. Pick type Secret and mode Test, and tick the scopes you need. Copy the key when it is shown. It is shown only once.

Test keys run the whole pipeline (checks, duplicates, spam rules) but write to a sandbox. You see their submissions on the key's page under Sandbox submissions.

2. Send a lead

Send a POST request with the lead's details. full_name is required, plus a phone number or an email, and consent must be true.

curl
curl -X POST "https://api.visaflow.work/v1/leads" \
  -H "Authorization: Bearer vf_test_xxxxxxxx_PASTE_THE_REST_OF_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "full_name": "PW Sample Lead",
  "phone": "+919000000001",
  "email": "sample.lead@example.test",
  "country_interest": "CA",
  "visa_type": "student",
  "intake": "2027-09",
  "message": "Interested in a postgraduate diploma",
  "consent": true
}'

3. Read the answer

3. Read the answer
StatusWhat it means
201A new lead was created. The body has its id, stage and who it was assigned to.
200We already had this person (same phone or email). Your submission was added to their timeline and the body says duplicate: true.
4xxSomething needs fixing. See Errors.

4. Read and update leads from your systems

With the leads:read scope you can list leads changed since a time, newest last, 100 at a time.

curl
curl "https://api.visaflow.work/v1/leads?updated_since=2026-10-01T00:00:00Z&limit=50" \
  -H "Authorization: Bearer vf_test_xxxxxxxx_PASTE_THE_REST_OF_YOUR_KEY"

# Next page: pass the next_cursor value from the previous answer
curl "https://api.visaflow.work/v1/leads?updated_since=2026-10-01T00:00:00Z&limit=50&cursor=NEXT_CURSOR" \
  -H "Authorization: Bearer vf_test_xxxxxxxx_PASTE_THE_REST_OF_YOUR_KEY"

Get one lead by id:

curl
curl "https://api.visaflow.work/v1/leads/LEAD_ID" \
  -H "Authorization: Bearer vf_test_xxxxxxxx_PASTE_THE_REST_OF_YOUR_KEY"

With the leads:update scope you can move a lead, set its temperature or follow-up, or add a note. The note shows on the lead's timeline with your key as the author.

curl
curl -X PATCH "https://api.visaflow.work/v1/leads/LEAD_ID" \
  -H "Authorization: Bearer vf_test_xxxxxxxx_PASTE_THE_REST_OF_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "stage_key": "contacted",
  "temperature": "warm",
  "next_follow_up_at": "2026-10-10T05:30:00Z",
  "note": "Called from our CRM. Asked for a callback next week."
}'

With the applications:read scope you can follow an application's stage and progress:

curl
curl "https://api.visaflow.work/v1/applications/APPLICATION_ID/status" \
  -H "Authorization: Bearer vf_test_xxxxxxxx_PASTE_THE_REST_OF_YOUR_KEY"

# {
#   "id": "APPLICATION_ID",
#   "reference": "APP-000123",
#   "stage": { "key": "offer_received", "name": "Offer received", "position": 5 },
#   "progress": 33,
#   "status": "active",
#   "outcome": null,
#   "module": { "key": "offer_letter", "name": "Offer Letter" },
#   "modules": [
#     { "key": "lead", "name": "Lead", "state": "updated" },
#     { "key": "consultant", "name": "Consultant", "state": "updated" },
#     { "key": "documentation", "name": "Documentation", "state": "updated" },
#     { "key": "offer_letter", "name": "Offer Letter", "state": "updated" },
#     { "key": "fee", "name": "Fee", "state": "pending" },
#     ...
#   ],
#   "current_module": { "key": "fee", "name": "Fee" },
#   "module_progress": { "updated": 4, "total": 12 }
# }

Your workspace's custom fields and allowed values:

curl
curl "https://api.visaflow.work/v1/meta/fields" \
  -H "Authorization: Bearer vf_test_xxxxxxxx_PASTE_THE_REST_OF_YOUR_KEY"

Next steps