curl --request POST \
--url https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"first_name": "Sarah",
"last_name": "Connor",
"email": "sarah@example.com",
"mobile": "+971501234567",
"inquiry_details": "Interested in Maldives package",
"source": "website",
"priority": 2,
"lead_status": "New",
"tags": [
"vip",
"corporate"
]
}
'import requests
url = "https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads"
payload = {
"first_name": "Sarah",
"last_name": "Connor",
"email": "sarah@example.com",
"mobile": "+971501234567",
"inquiry_details": "Interested in Maldives package",
"source": "website",
"priority": 2,
"lead_status": "New",
"tags": ["vip", "corporate"]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
first_name: 'Sarah',
last_name: 'Connor',
email: 'sarah@example.com',
mobile: '+971501234567',
inquiry_details: 'Interested in Maldives package',
source: 'website',
priority: 2,
lead_status: 'New',
tags: ['vip', 'corporate']
})
};
fetch('https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'first_name' => 'Sarah',
'last_name' => 'Connor',
'email' => 'sarah@example.com',
'mobile' => '+971501234567',
'inquiry_details' => 'Interested in Maldives package',
'source' => 'website',
'priority' => 2,
'lead_status' => 'New',
'tags' => [
'vip',
'corporate'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads"
payload := strings.NewReader("{\n \"first_name\": \"Sarah\",\n \"last_name\": \"Connor\",\n \"email\": \"sarah@example.com\",\n \"mobile\": \"+971501234567\",\n \"inquiry_details\": \"Interested in Maldives package\",\n \"source\": \"website\",\n \"priority\": 2,\n \"lead_status\": \"New\",\n \"tags\": [\n \"vip\",\n \"corporate\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"first_name\": \"Sarah\",\n \"last_name\": \"Connor\",\n \"email\": \"sarah@example.com\",\n \"mobile\": \"+971501234567\",\n \"inquiry_details\": \"Interested in Maldives package\",\n \"source\": \"website\",\n \"priority\": 2,\n \"lead_status\": \"New\",\n \"tags\": [\n \"vip\",\n \"corporate\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"first_name\": \"Sarah\",\n \"last_name\": \"Connor\",\n \"email\": \"sarah@example.com\",\n \"mobile\": \"+971501234567\",\n \"inquiry_details\": \"Interested in Maldives package\",\n \"source\": \"website\",\n \"priority\": 2,\n \"lead_status\": \"New\",\n \"tags\": [\n \"vip\",\n \"corporate\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"email": "<string>",
"mobile": "<string>",
"lead_status": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"lead_source": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"assigned_to": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"full_name": "<string>",
"email": "jsmith@example.com"
},
"priority": 123,
"lead_score": 123,
"tags_applied": [
"<string>"
],
"duplicate_warning": "<string>",
"created_at": "2023-11-07T05:31:56Z"
},
"meta": {
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z",
"rate_limit": {
"limit": 123,
"remaining": 123,
"reset": 123
}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": {
"fields": {
"first_name": "First name is required"
}
}
},
"meta": {
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-02-15T10:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "AUTH_INVALID_KEY",
"message": "Invalid API key"
},
"meta": {
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-02-15T10:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "MISSING_API_KEY",
"message": "<string>",
"details": "<unknown>"
},
"meta": {
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z",
"rate_limit": {
"limit": 123,
"remaining": 123,
"reset": 123
}
}
}{
"success": false,
"error": {
"code": "MISSING_API_KEY",
"message": "<string>",
"details": "<unknown>"
},
"meta": {
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z",
"rate_limit": {
"limit": 123,
"remaining": 123,
"reset": 123
}
}
}{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 12 seconds.",
"details": {
"limit": 60,
"remaining": 0,
"reset": 1718400000000,
"retry_after": 12
}
},
"meta": {
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-02-15T10:00:00.000Z"
}
}Create a new lead
Creates a new lead with optional custom fields, tags, source, status, and user assignment. Validates against the company’s configured lead statuses and sources.
If the company has duplicate detection enabled, returns 409 when a
lead with the same email already exists.
Required scope: leads:write
curl --request POST \
--url https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"first_name": "Sarah",
"last_name": "Connor",
"email": "sarah@example.com",
"mobile": "+971501234567",
"inquiry_details": "Interested in Maldives package",
"source": "website",
"priority": 2,
"lead_status": "New",
"tags": [
"vip",
"corporate"
]
}
'import requests
url = "https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads"
payload = {
"first_name": "Sarah",
"last_name": "Connor",
"email": "sarah@example.com",
"mobile": "+971501234567",
"inquiry_details": "Interested in Maldives package",
"source": "website",
"priority": 2,
"lead_status": "New",
"tags": ["vip", "corporate"]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
first_name: 'Sarah',
last_name: 'Connor',
email: 'sarah@example.com',
mobile: '+971501234567',
inquiry_details: 'Interested in Maldives package',
source: 'website',
priority: 2,
lead_status: 'New',
tags: ['vip', 'corporate']
})
};
fetch('https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'first_name' => 'Sarah',
'last_name' => 'Connor',
'email' => 'sarah@example.com',
'mobile' => '+971501234567',
'inquiry_details' => 'Interested in Maldives package',
'source' => 'website',
'priority' => 2,
'lead_status' => 'New',
'tags' => [
'vip',
'corporate'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads"
payload := strings.NewReader("{\n \"first_name\": \"Sarah\",\n \"last_name\": \"Connor\",\n \"email\": \"sarah@example.com\",\n \"mobile\": \"+971501234567\",\n \"inquiry_details\": \"Interested in Maldives package\",\n \"source\": \"website\",\n \"priority\": 2,\n \"lead_status\": \"New\",\n \"tags\": [\n \"vip\",\n \"corporate\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"first_name\": \"Sarah\",\n \"last_name\": \"Connor\",\n \"email\": \"sarah@example.com\",\n \"mobile\": \"+971501234567\",\n \"inquiry_details\": \"Interested in Maldives package\",\n \"source\": \"website\",\n \"priority\": 2,\n \"lead_status\": \"New\",\n \"tags\": [\n \"vip\",\n \"corporate\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api/v1/leads")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"first_name\": \"Sarah\",\n \"last_name\": \"Connor\",\n \"email\": \"sarah@example.com\",\n \"mobile\": \"+971501234567\",\n \"inquiry_details\": \"Interested in Maldives package\",\n \"source\": \"website\",\n \"priority\": 2,\n \"lead_status\": \"New\",\n \"tags\": [\n \"vip\",\n \"corporate\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"email": "<string>",
"mobile": "<string>",
"lead_status": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"lead_source": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"assigned_to": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"full_name": "<string>",
"email": "jsmith@example.com"
},
"priority": 123,
"lead_score": 123,
"tags_applied": [
"<string>"
],
"duplicate_warning": "<string>",
"created_at": "2023-11-07T05:31:56Z"
},
"meta": {
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z",
"rate_limit": {
"limit": 123,
"remaining": 123,
"reset": 123
}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": {
"fields": {
"first_name": "First name is required"
}
}
},
"meta": {
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-02-15T10:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "AUTH_INVALID_KEY",
"message": "Invalid API key"
},
"meta": {
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-02-15T10:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "MISSING_API_KEY",
"message": "<string>",
"details": "<unknown>"
},
"meta": {
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z",
"rate_limit": {
"limit": 123,
"remaining": 123,
"reset": 123
}
}
}{
"success": false,
"error": {
"code": "MISSING_API_KEY",
"message": "<string>",
"details": "<unknown>"
},
"meta": {
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z",
"rate_limit": {
"limit": 123,
"remaining": 123,
"reset": 123
}
}
}{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 12 seconds.",
"details": {
"limit": 60,
"remaining": 0,
"reset": 1718400000000,
"retry_after": 12
}
},
"meta": {
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-02-15T10:00:00.000Z"
}
}Authorizations
API key from Settings > API Keys or POST /v1/api-keys. Format
f9_live_<32 hex chars> (live) or f9_test_<32 hex chars> (sandbox — no
real sends, ever). Legacy wcrm_live_ / wcrm_test_ keys still
authenticate but are no longer issued. Shown once at creation; only a hash
is stored.
Headers
Opaque client-generated key that makes a retried POST safe. Resending the same key with the SAME body replays the original response (marked with Idempotent-Replay: true) instead of creating a second record. Resending it with a DIFFERENT body is rejected with 422. Keys are scoped to your company and to the endpoint, and expire after 24 hours.
8 - 255^[A-Za-z0-9_.:@+\-]+$Body
1 - 100At least one of email or mobile is required.
At least one of email or mobile is required.
50005000Lead source name (resolved against company's configured sources).
1 <= x <= 4Email of the user to assign. Must be an active user in the company.
Lead status name (resolved against company's configured statuses).