Skip to content

Capture leads from your website

Someone filled in the contact form on your website. With one call, that contact lands in Faturei Hoje as a lead and a task is opened for someone on the team to get back to them.

visitor's browser -> your server -> POST /public/v1/leads

The form posts to your server, and your server calls the API. The key never goes to the browser: anyone who opened the page source would walk away with it.

The API has no bot protection for your form. Spam filtering, captcha and per-visitor limits are on your side, before the call.

Create a key just for the website, with the minimum:

PermissionWhat for
leads:createRegister the lead
tasks:createOpen the contact task. Without it, you can only register with task: null
team:readOptional. Only if you are going to choose who owns the task

The member the key acts as needs access to clients in the dashboard and, when the capture opens a task, to tasks as well. See Permissions.

POST /public/v1/leads takes the name and at least one contact, email or phone. With neither, the response is 422.

Terminal window
# Generate the key once and keep it: on a retry, repeat with the same value.
LEAD_KEY=$(uuidgen)
curl -X POST "https://api.fatureihoje.com/public/v1/leads" \
-H "Authorization: Bearer $FH_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $LEAD_KEY" \
-d '{
"name": "Ana Souza",
"email": "ana@example.com",
"phone": "+5511999990000",
"source": "website",
"notes": "I would like a quote for installing security cameras.",
"task": { "due_in_hours": 4, "priority": "high" }
}'

What each field does, with its maximum length, is in the Reference. The ones worth a comment:

  • source says where the lead came from. Use one value per form or campaign (website, black-friday-landing) and you can tell leads apart later.
  • notes is the message the person wrote. It goes to the record’s notes.
  • task controls the contact task. Without the field, the default task opens, due in 24 hours. With an object, you choose title, description, due time (due_in_hours or due_at, one or the other), priority and owner. With task: null, no task is opened.

The response is 201 with a lead_capture object:

  • lead: the record, with its id. That id is the client’s id and works in GET /public/v1/clients/{id}.
  • task: the contact task that was opened, or null when you sent task: null.
  • deduplicated: true when the record already existed.

If the phone or the email already belongs to one of the company’s records, the API reuses that record and overwrites nothing: not the name, not the contact details, not the status. An active client who fills in the form again stays active. The contact task opens all the same, because someone still needs to reply.

When that happens and the key has neither leads:read nor clients:read, lead and task come with only object and id. That is on purpose: a key that only registers does not read the record of someone who was already there.

Without an owner, the task is created unassigned. To send it to someone, look the person up in GET /public/v1/team and send their id in task.assignee_id, together with their type in task.assignee_type. One without the other returns 422.

POST /public/v1/leads
{
"name": "Ana Souza",
"phone": "+5511999990000",
"task": {
"assignee_id": "3f6c2a9e-8b1d-4e5f-9a7c-2d4b6e8f0a1c",
"assignee_type": "org_member"
}
}

The team list rarely changes. Read it once and keep it, instead of fetching it for every lead.

Store the form submission on your side before calling the API. If the call fails on network, timeout, 429 or 5xx, try again later with the same Idempotency-Key: the lead is not registered twice. See Idempotency.

ResponseWhat to do
422 validation_failedFix the field listed in errors. Retrying as is will not help
403 permission_missingThe key is missing a permission, usually tasks:create
403 member_permission_deniedThe key’s member has no access to clients in the dashboard, or to tasks when the capture opens a task
429 rate_limit_exceededWait for Retry-After and retry. See Rate limits
5xx or network failureRetry with the same Idempotency-Key

The full catalog is in Errors.

  • Sync clients with a CRM or ERP: take the record into your system.
  • Webhooks: the client.created event tells your system when a new record comes in, whether from the website, the dashboard or WhatsApp.