{"openapi":"3.1.0","info":{"title":"VisaFlow Public API","version":"1.0.0","description":"Lead capture, lead sync, application status and webhooks. snake_case JSON. Authenticate with `Authorization: Bearer <key>`: public keys (`vf_live_pub_...`) only create leads from allowed origins; secret keys (`vf_live_...`) are for servers and act on the whole workspace within their scopes. Every answer carries `RateLimit-*` headers; errors are `{ error, message, ..., request_id }`."},"servers":[{"url":"https://api.visaflow.work","description":"Public API host"}],"security":[{"secretKey":[]}],"tags":[{"name":"Leads"},{"name":"Applications"},{"name":"Webhooks"},{"name":"Meta"}],"paths":{"/v1/leads":{"post":{"tags":["Leads"],"operationId":"createLead","summary":"Create a lead (public or secret key, scope leads:create)","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{1,255}$"},"description":"Repeats within 24 h answer the first result"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadCreate"}}}},"responses":{"200":{"description":"Matched an existing lead (enquiry added)","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadDuplicate"}}}},"201":{"description":"Lead created","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadCreated"}}}},"400":{"description":"Validation failed (`validation_failed` with `fields`) or a business rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict (`lead_locked`, `stage_requires_conversion`, `webhook_limit`, ...)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Leads"],"operationId":"listLeads","summary":"List leads ordered by (updated_at, id) (secret key, leads:read)","parameters":[{"name":"updated_since","in":"query","required":false,"schema":{"description":"Only leads updated at or after this instant","type":"string","format":"date-time"},"description":"Only leads updated at or after this instant"},{"name":"cursor","in":"query","required":false,"schema":{"description":"`next_cursor` of the previous page","type":"string","maxLength":200},"description":"`next_cursor` of the previous page"},{"name":"limit","in":"query","required":false,"schema":{"default":25,"description":"Page size, 1 to 100","type":"integer","minimum":1,"maximum":100},"description":"Page size, 1 to 100"}],"responses":{"200":{"description":"A page of leads","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadList"}}}},"400":{"description":"Validation failed (`validation_failed` with `fields`) or a business rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/leads/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Lead id"}],"get":{"tags":["Leads"],"operationId":"getLead","summary":"Get a lead (secret key, leads:read)","responses":{"200":{"description":"The lead","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lead"}}}},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Leads"],"operationId":"updateLead","summary":"Update stage, lost reason, temperature, follow-up, owner, custom fields or add a note (secret key, leads:update)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadPatch"}}}},"responses":{"200":{"description":"The updated lead","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lead"}}}},"400":{"description":"Validation failed (`validation_failed` with `fields`) or a business rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict (`lead_locked`, `stage_requires_conversion`, `webhook_limit`, ...)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/applications/{id}/status":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Application id"}],"get":{"tags":["Applications"],"operationId":"getApplicationStatus","summary":"Application stage and progress (secret key, applications:read)","responses":{"200":{"description":"Status","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationStatus"}}}},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/webhooks":{"get":{"tags":["Webhooks"],"operationId":"listWebhooks","summary":"List webhook endpoints (secret key, webhooks:manage; Growth and Enterprise plans)","responses":{"200":{"description":"Endpoints","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"required":["data"]}}}},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Webhooks"],"operationId":"createWebhook","summary":"Create a webhook endpoint; the signing secret is returned once","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreate"}}}},"responses":{"201":{"description":"Created","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreated"}}}},"400":{"description":"Validation failed (`validation_failed` with `fields`) or a business rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict (`lead_locked`, `stage_requires_conversion`, `webhook_limit`, ...)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/webhooks/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Webhook endpoint id"}],"delete":{"tags":["Webhooks"],"operationId":"deleteWebhook","summary":"Delete a webhook endpoint","responses":{"204":{"description":"Deleted"},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/widget/config":{"get":{"tags":["Meta"],"operationId":"getWidgetConfig","summary":"Embed widget configuration (public key with leads:create, origin-checked)","description":"The public key is passed as `?key=` (no Authorization header). The request `Origin` must match one of the key's allowed origins; the answer then carries `Access-Control-Allow-Origin` for it, otherwise 403 `origin_not_allowed`. Secret keys get 403 `insufficient_scope` (`required: public_key`).","security":[],"parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string"},"description":"Public key `vf_{live|test}_pub_...`"},{"name":"Origin","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Widget configuration","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WidgetConfig"}}}},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/meta/fields":{"get":{"tags":["Meta"],"operationId":"getMetaFields","summary":"Custom fields, visa types and countries (secret key)","responses":{"200":{"description":"Fields","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetaFields"}}}},"401":{"description":"`invalid_api_key`: missing, unknown, revoked or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`tenant_suspended`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope`, `ip_not_allowed`, `origin_not_allowed`, `plan_feature_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited` (with `scope` and `retry_after`) or `quota_exceeded`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"lead.created":{"post":{"summary":"lead.created delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"lead.created"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"lead.updated":{"post":{"summary":"lead.updated delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"lead.updated"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"lead.assigned":{"post":{"summary":"lead.assigned delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"lead.assigned"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"lead.converted":{"post":{"summary":"lead.converted delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"lead.converted"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"lead.lost":{"post":{"summary":"lead.lost delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"lead.lost"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"application.stage_changed":{"post":{"summary":"application.stage_changed delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed. Sent when the case moves to another workflow stage, also when the move comes from roadmap module updates. `data.stage_change` describes the move from the event (stage ids and keys, the modules covering them, passed stages). Kept for compatibility; new integrations should subscribe to `application.module_updated`.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"application.stage_changed"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationWebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"application.module_updated":{"post":{"summary":"application.module_updated delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed. Sent once per roadmap module change: marked updated or pending, switched on or off, restored or added to the case. Saving module details without a state change sends nothing. `data.module_event` describes the change from the event; module names are the names shown on the case, including custom modules.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"application.module_updated"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationWebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"application.outcome":{"post":{"summary":"application.outcome delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"application.outcome"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationWebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"document.uploaded":{"post":{"summary":"document.uploaded delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"document.uploaded"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"document.rejected":{"post":{"summary":"document.rejected delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"document.rejected"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"invoice.issued":{"post":{"summary":"invoice.issued delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"invoice.issued"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"payment.received":{"post":{"summary":"payment.received delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"payment.received"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"task.overdue":{"post":{"summary":"task.overdue delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"task.overdue"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"refund.paid":{"post":{"summary":"refund.paid delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"refund.paid"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}},"webhook.test":{"post":{"summary":"webhook.test delivery","description":"POST to your endpoint. Verify `X-VisaFlow-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>` (two `v1` values during the 24 h after a secret rotation) and reject timestamps older than 5 minutes. Answer 2xx within 10 s; otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h. Redirects are not followed.","parameters":[{"name":"X-VisaFlow-Event","in":"header","required":true,"schema":{"type":"string","const":"webhook.test"}},{"name":"X-VisaFlow-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-VisaFlow-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery"}}}}},"components":{"securitySchemes":{"secretKey":{"type":"http","scheme":"bearer","bearerFormat":"VisaFlow API key"}},"headers":{"RateLimit-Limit":{"description":"Bucket capacity of the most constrained layer","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that bucket","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the bucket is full again","schema":{"type":"integer"}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"snake_case error code"},"message":{"type":"string"},"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"scope":{"type":"string"},"retry_after":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"required":{"type":"string"},"request_id":{"type":"string"}},"required":["error","message","request_id"],"description":"Every non-2xx answer"},"LeadCreate":{"type":"object","properties":{"full_name":{"type":"string","minLength":1,"maxLength":120},"phone":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}]},"email":{"anyOf":[{"anyOf":[{"type":"string","const":""},{"type":"string"}]},{"type":"null"}]},"alt_phone":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"state":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"country_interest":{"type":["string","null"]},"visa_type":{"anyOf":[{"type":"string","enum":["student","work","pr","visitor","spouse_dependent","business"]},{"type":"null"}]},"intake":{"anyOf":[{"type":"string","pattern":"^(\\d{4})-(0[1-9]|1[0-2])$"},{"type":"null"}]},"course":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"date_of_birth":{"type":["string","null"]},"highest_qualification":{"anyOf":[{"type":"string","enum":["secondary","higher_secondary","diploma","bachelors","masters","doctorate","other"]},{"type":"null"}]},"score_percent":{"anyOf":[{"type":"number","minimum":0,"maximum":100},{"type":"null"}]},"english_test":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["IELTS","PTE","TOEFL","DUOLINGO"]},"overall":{"type":"number"},"listening":{"type":"number"},"reading":{"type":"number"},"writing":{"type":"number"},"speaking":{"type":"number"},"test_date":{"type":"string"}},"required":["type","overall"],"additionalProperties":false},{"type":"null"}]},"work_experience_years":{"anyOf":[{"type":"number","minimum":0,"maximum":60},{"type":"null"}]},"passport_available":{"type":["boolean","null"]},"previous_refusals":{"anyOf":[{"type":"integer","minimum":0,"maximum":20},{"type":"null"}]},"message":{"type":"string","maxLength":2000},"utm":{"anyOf":[{"type":"object","properties":{"source":{"type":"string","maxLength":200},"medium":{"type":"string","maxLength":200},"campaign":{"type":"string","maxLength":200},"term":{"type":"string","maxLength":200},"content":{"type":"string","maxLength":200}},"additionalProperties":false},{"type":"null"}]},"landing_page_url":{"anyOf":[{"type":"string","maxLength":2000,"format":"uri"},{"type":"null"}]},"custom_fields":{"type":"object","additionalProperties":true,"description":"Tenant custom fields (GET /v1/meta/fields)"},"consent":{"const":true,"description":"Must be true (DPDP); else 400 consent_required"},"captcha_token":{"type":"string","description":"Required for public keys"},"website":{"type":"string","description":"Honeypot: leave empty"}},"required":["full_name","consent"],"additionalProperties":false,"description":"At least one of phone / email is required"},"LeadCreated":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","description":"Stage key of the new lead"},"assigned_to":{"type":["string","null"]},"duplicate":{"const":false},"test_mode":{"type":"boolean"}},"required":["id","status","assigned_to","duplicate"]},"LeadDuplicate":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"duplicate":{"const":true}},"required":["id","duplicate"]},"Lead":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"full_name":{"type":"string"},"phone":{"anyOf":[{"type":"string","description":"E.164"},{"type":"null"}]},"alt_phone":{"type":["string","null"]},"email":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"country_interest":{"anyOf":[{"type":"string","description":"ISO 3166-1 alpha-2"},{"type":"null"}]},"visa_type":{"anyOf":[{"type":"string","enum":["student","work","pr","visitor","spouse_dependent","business"]},{"type":"null"}]},"intake":{"anyOf":[{"type":"string","description":"YYYY-MM"},{"type":"null"}]},"course":{"type":["string","null"]},"date_of_birth":{"anyOf":[{"type":"string","description":"YYYY-MM-DD"},{"type":"null"}]},"highest_qualification":{"anyOf":[{"type":"string","enum":["secondary","higher_secondary","diploma","bachelors","masters","doctorate","other"]},{"type":"null"}]},"score_percent":{"type":["number","null"]},"english_test":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["IELTS","PTE","TOEFL","DUOLINGO"]},"overall":{"type":"number"},"listening":{"type":"number"},"reading":{"type":"number"},"writing":{"type":"number"},"speaking":{"type":"number"},"test_date":{"type":"string"}},"required":["type","overall"],"additionalProperties":false},{"type":"null"}]},"work_experience_years":{"type":["number","null"]},"passport_available":{"type":["boolean","null"]},"previous_refusals":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"source":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"additionalProperties":false},"campaign":{"type":["string","null"]},"utm":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},{"type":"null"}]},"landing_page_url":{"type":["string","null"]},"branch":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"}},"required":["id","code"],"additionalProperties":false},"owner":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"}},"required":["id","name","email"],"additionalProperties":false},{"type":"null"}]},"stage":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"additionalProperties":false},"temperature":{"anyOf":[{"type":"string","enum":["hot","warm","cold"]},{"type":"null"}]},"score":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"next_follow_up_at":{"anyOf":[{"type":"string","description":"ISO 8601 UTC date-time"},{"type":"null"}]},"lost_reason":{"anyOf":[{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"additionalProperties":false},{"type":"null"}]},"converted":{"type":"boolean"},"custom_fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"consent":{"anyOf":[{"type":"object","properties":{"at":{"type":"string","description":"ISO 8601 UTC date-time"},"source":{"type":"string"}},"required":["at","source"],"additionalProperties":false},{"type":"null"}]},"created_at":{"type":"string","description":"ISO 8601 UTC date-time"},"updated_at":{"type":"string","description":"ISO 8601 UTC date-time"},"last_activity_at":{"anyOf":[{"type":"string","description":"ISO 8601 UTC date-time"},{"type":"null"}]},"stage_changed_at":{"anyOf":[{"type":"string","description":"ISO 8601 UTC date-time"},{"type":"null"}]}},"required":["id","full_name","phone","alt_phone","email","city","state","country_interest","visa_type","intake","course","date_of_birth","highest_qualification","score_percent","english_test","work_experience_years","passport_available","previous_refusals","source","campaign","utm","landing_page_url","branch","owner","stage","temperature","score","next_follow_up_at","lost_reason","converted","custom_fields","consent","created_at","updated_at","last_activity_at","stage_changed_at"],"additionalProperties":false,"description":"Lead (contract 20.4)"},"LeadList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` for the next page"}},"required":["data","next_cursor"]},"LeadPatch":{"type":"object","properties":{"stage_key":{"description":"Target stage key (15.4 rules; `converted` is not allowed)","type":"string","pattern":"^[a-z][a-z0-9_]{0,59}$"},"lost_reason_key":{"description":"Required when moving to the lost stage","anyOf":[{"type":"string","pattern":"^[a-z][a-z0-9_]{0,59}$"},{"type":"null"}]},"temperature":{"anyOf":[{"type":"string","enum":["hot","warm","cold"]},{"type":"null"}]},"next_follow_up_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"owner_email":{"description":"Email of an active user of the lead's branch; null unassigns","anyOf":[{"type":"string","format":"email"},{"type":"null"}]},"custom_fields":{"description":"Merged per key; null removes a key","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"note":{"type":"string","minLength":1,"maxLength":5000}},"additionalProperties":false},"ApplicationStatus":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reference":{"type":"string","description":"e.g. APP-000123 (kept as an alias of case_ref)"},"case_ref":{"type":"string","description":"Case reference, e.g. VF-2026-0012 (added in v1.2)"},"stage":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["key","name","position"],"additionalProperties":false},"progress":{"type":"integer","minimum":0,"maximum":100,"description":"Percent"},"status":{"type":"string","enum":["active","on_hold","closed"]},"outcome":{"anyOf":[{"type":"string","enum":["granted","refused","withdrawn"]},{"type":"null"}]},"module":{"anyOf":[{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"additionalProperties":false},{"type":"null"}],"description":"Roadmap module holding the case (added in v1.2)"},"modules":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"state":{"type":"string","enum":["pending","updated"]}},"required":["key","name","state"],"additionalProperties":false},"description":"Selected roadmap modules in order (added in v1.2)"},"current_module":{"anyOf":[{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"additionalProperties":false},{"type":"null"}],"description":"First selected module still pending that counts toward progress, in roadmap order; null when all are updated (added in v1.3). Can differ from `module`, for example an optional or custom module placed before it"},"module_progress":{"anyOf":[{"type":"object","properties":{"updated":{"type":"integer","minimum":0,"maximum":9007199254740991},"total":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["updated","total"],"additionalProperties":false},{"type":"null"}],"description":"Counts behind `progress`: updated / selected modules that count toward progress (added in v1.3)"}},"required":["id","reference","case_ref","stage","progress","status","outcome","module","modules","current_module","module_progress"],"additionalProperties":false},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string","enum":["lead.created","lead.updated","lead.assigned","lead.converted","lead.lost","application.stage_changed","application.module_updated","application.outcome","document.uploaded","document.rejected","invoice.issued","payment.received","task.overdue","refund.paid","webhook.test"]}},"status":{"type":"string","enum":["active","paused"]},"consecutive_failures":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"paused_reason":{"type":["string","null"]},"paused_at":{"anyOf":[{"type":"string","description":"ISO 8601 UTC date-time"},{"type":"null"}]},"previous_secret_valid_until":{"anyOf":[{"type":"string","description":"ISO 8601 UTC date-time"},{"type":"null"}]},"created_at":{"type":"string","description":"ISO 8601 UTC date-time"},"updated_at":{"type":"string","description":"ISO 8601 UTC date-time"}},"required":["id","url","description","events","status","consecutive_failures","paused_reason","paused_at","previous_secret_valid_until","created_at","updated_at"],"additionalProperties":false},"WebhookEndpointCreate":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"events":{"minItems":1,"maxItems":15,"type":"array","items":{"type":"string"}}},"required":["url","events"],"additionalProperties":false},"WebhookEndpointCreated":{"allOf":[{"$ref":"#/components/schemas/WebhookEndpoint"},{"type":"object","properties":{"secret":{"type":"string","pattern":"^whsec_[A-Za-z0-9]{32}$","description":"Shown once"}},"required":["secret"]}]},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Event id: the same for every attempt and resend; use it to ignore duplicates"},"event":{"type":"string"},"tenant_id":{"type":"string","format":"uuid"},"created_at":{"type":"string","description":"ISO 8601 UTC date-time"},"data":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The resource in its public API shape"}},"required":["id","event","tenant_id","created_at","data"],"additionalProperties":false},"ApplicationWebhookEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Event id: the same for every attempt and resend; use it to ignore duplicates"},"event":{"type":"string"},"tenant_id":{"type":"string","format":"uuid"},"created_at":{"type":"string","description":"ISO 8601 UTC date-time"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reference":{"type":"string","description":"e.g. APP-000123 (kept as an alias of case_ref)"},"case_ref":{"type":"string","description":"Case reference, e.g. VF-2026-0012 (added in v1.2)"},"stage":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["key","name","position"],"additionalProperties":false},"progress":{"type":"integer","minimum":0,"maximum":100,"description":"Percent"},"status":{"type":"string","enum":["active","on_hold","closed"]},"outcome":{"anyOf":[{"type":"string","enum":["granted","refused","withdrawn"]},{"type":"null"}]},"module":{"anyOf":[{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"additionalProperties":false},{"type":"null"}],"description":"Roadmap module holding the case (added in v1.2)"},"modules":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"state":{"type":"string","enum":["pending","updated"]}},"required":["key","name","state"],"additionalProperties":false},"description":"Selected roadmap modules in order (added in v1.2)"},"current_module":{"anyOf":[{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"additionalProperties":false},{"type":"null"}],"description":"First selected module still pending that counts toward progress, in roadmap order; null when all are updated (added in v1.3). Can differ from `module`, for example an optional or custom module placed before it"},"module_progress":{"anyOf":[{"type":"object","properties":{"updated":{"type":"integer","minimum":0,"maximum":9007199254740991},"total":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["updated","total"],"additionalProperties":false},{"type":"null"}],"description":"Counts behind `progress`: updated / selected modules that count toward progress (added in v1.3)"},"stage_change":{"description":"Only on application.stage_changed: the move from the event, not from delivery time","type":"object","properties":{"from_stage_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"to_stage_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"direction":{"anyOf":[{"type":"string","enum":["forward","backward","initial"]},{"type":"null"}]},"passed_stage_ids":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Forward moves: every stage entered, skipped ones included, target last (added in v1.2)"},"from_stage_key":{"description":"Added in v1.3","type":["string","null"]},"to_stage_key":{"description":"Added in v1.3","type":["string","null"]},"from_module":{"anyOf":[{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"additionalProperties":false},{"type":"null"}],"description":"Case module covering the previous stage (added in v1.3)"},"to_module":{"anyOf":[{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"}},"required":["key","name"],"additionalProperties":false},{"type":"null"}],"description":"Case module covering the new stage (added in v1.3)"}},"required":["from_stage_id","to_stage_id","direction","passed_stage_ids","from_stage_key","to_stage_key","from_module","to_module"],"additionalProperties":false},"module_event":{"description":"Only on application.module_updated: the module change from the event (added in v1.2)","type":"object","properties":{"key":{"type":["string","null"]},"name":{"type":["string","null"]},"kind":{"anyOf":[{"type":"string","enum":["state","selected","deselected","restored","added","fields"]},{"type":"null"}]},"from_state":{"anyOf":[{"type":"string","enum":["pending","updated"]},{"type":"null"}]},"to_state":{"anyOf":[{"type":"string","enum":["pending","updated"]},{"type":"null"}]},"selected":{"type":["boolean","null"]}},"required":["key","name","kind","from_state","to_state","selected"],"additionalProperties":false}},"required":["id","reference","case_ref","stage","progress","status","outcome","module","modules","current_module","module_progress"],"additionalProperties":false,"description":"Application status at fan-out time (same shape as GET /v1/applications/{id}/status) plus the event fields"}},"required":["id","event","tenant_id","created_at","data"],"additionalProperties":false},"WidgetConfig":{"type":"object","properties":{"tenant":{"type":"object","properties":{"name":{"type":"string"},"brand_color":{"type":["string","null"]},"logo_url":{"type":["string","null"]}},"required":["name","brand_color","logo_url"]},"fields":{"$ref":"#/components/schemas/MetaFields/properties/fields"},"visa_types":{"type":"array","items":{"type":"string","enum":["student","work","pr","visitor","spouse_dependent","business"]}},"countries":{"type":"array","items":{"type":"string"}},"captcha":{"type":"object","properties":{"provider":{"type":"string"},"site_key":{"type":["string","null"]}},"required":["provider","site_key"]},"consent_text":{"type":"string"},"consent_text_version":{"type":"string"},"test_mode":{"type":"boolean"}},"required":["tenant","fields","visa_types","countries","captcha","consent_text","consent_text_version","test_mode"]},"MetaFields":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"type":{"type":"string","enum":["text","number","date","dropdown","checkbox"]},"required":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"}}}},"help_text":{"type":["string","null"]}}}},"visa_types":{"type":"array","items":{"type":"string","enum":["student","work","pr","visitor","spouse_dependent","business"]}},"countries":{"type":"array","items":{"type":"string"}}},"required":["fields","visa_types","countries"]}}}}