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 -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
| Status | What it means |
|---|---|
201 | A new lead was created. The body has its id, stage and who it was assigned to. |
200 | We already had this person (same phone or email). Your submission was added to their timeline and the body says duplicate: true. |
4xx | Something 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 "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 "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 -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 "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 "https://api.visaflow.work/v1/meta/fields" \
-H "Authorization: Bearer vf_test_xxxxxxxx_PASTE_THE_REST_OF_YOUR_KEY"Next steps
- Get told about changes instead of polling: set up webhooks.
- Ready for real leads? Create a live key with the same settings and swap it in.