curl --request POST \
--url https://api.vaquill.ai/workspace/v1/clients \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme Corporation"
}
'import requests
url = "https://api.vaquill.ai/workspace/v1/clients"
payload = { "name": "Acme Corporation" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Acme Corporation'})
};
fetch('https://api.vaquill.ai/workspace/v1/clients', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/workspace/v1/clients"
payload := strings.NewReader("{\n \"name\": \"Acme Corporation\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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))
}{
"id": "cli_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"name": "Acme Corporation",
"email": "counsel@acme.example",
"phone": "+1 415 555 0142",
"address": "500 Howard Street",
"city": "San Francisco",
"state": "CA",
"zipCode": "94105",
"country": "US",
"clientType": "organization",
"taxId": "94-3211110",
"notes": "Primary contact is in-house counsel, not procurement.",
"metadata": {
"externalId": "CRM-4471"
},
"createdAt": "2026-08-19T14:32:10Z",
"updatedAt": "2026-08-19T14:32:10Z"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"errors": [
{
"location": "<string>",
"message": "<string>",
"type": "<string>"
}
],
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}Create a client
Create a client.
The organization comes from the credential, so there is no field for it and
sending one is refused. Only name is required; everything else can be
filled in later with a PATCH. Clients cannot be deleted through this API.
curl --request POST \
--url https://api.vaquill.ai/workspace/v1/clients \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme Corporation"
}
'import requests
url = "https://api.vaquill.ai/workspace/v1/clients"
payload = { "name": "Acme Corporation" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Acme Corporation'})
};
fetch('https://api.vaquill.ai/workspace/v1/clients', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/workspace/v1/clients"
payload := strings.NewReader("{\n \"name\": \"Acme Corporation\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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))
}{
"id": "cli_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"name": "Acme Corporation",
"email": "counsel@acme.example",
"phone": "+1 415 555 0142",
"address": "500 Howard Street",
"city": "San Francisco",
"state": "CA",
"zipCode": "94105",
"country": "US",
"clientType": "organization",
"taxId": "94-3211110",
"notes": "Primary contact is in-house counsel, not procurement.",
"metadata": {
"externalId": "CRM-4471"
},
"createdAt": "2026-08-19T14:32:10Z",
"updatedAt": "2026-08-19T14:32:10Z"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"errors": [
{
"location": "<string>",
"message": "<string>",
"type": "<string>"
}
],
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}{
"type": "https://vaquill.ai/docs/workspace-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential carries matters:read. This operation needs matters:write.",
"instance": "/workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6",
"requestId": "req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
}Authorizations
Workspace credential issued from the automation console at /automation. Send it as Authorization: Bearer vq_ws_.... This is NOT a Data API key: a vq_key_ credential is refused here and names the other product in the error.
Body
Everything a caller may set when creating a client.
The client's display name. Trimmed; whitespace alone is refused.
1 - 200"Acme Corporation"
Primary contact email address. Validated for shape, never sent to.
255"counsel@acme.example"
Primary contact phone number. Stored verbatim, not normalized.
30"+1 415 555 0142"
Street address, one free-text line.
500"500 Howard Street"
City or town.
100"San Francisco"
State, province or region.
100"CA"
Postal or ZIP code.
20"94105"
Country as free text. Unlike a matter's country, this is NOT an ISO code and is not validated as one.
100"US"
What kind of client this is. Defaults to individual.
individual, organization, corporation "individual"
Tax or company registration number.
50"94-3211110"
Free-text notes to keep against this client.
10000"Primary contact is in-house counsel, not procurement."
Arbitrary JSON to store against the client. Vaquill never reads it.
Response
Successful Response
A client as this API publishes it.
Public identifier, cli_ followed by 32 hex characters.
"cli_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6"
The client's display name, as the customer entered it.
"Acme Corporation"
Primary contact email address.
"counsel@acme.example"
Primary contact phone number, stored as written and not normalized.
"+1 415 555 0142"
Street address, one free-text line.
"500 Howard Street"
City or town.
"San Francisco"
State, province or region.
"CA"
Postal or ZIP code.
"94105"
Country as free text, NOT an ISO code. matters.country is a two-letter code; this column is not.
"US"
What kind of client this is. Usually one of individual, organization or corporation, but published as a plain string because the column's CHECK is the only thing constraining it. Do not branch on it without a fallback.
"organization"
Tax or company registration number.
"94-3211110"
Free-text notes the customer keeps against this client.
"Primary contact is in-house counsel, not procurement."
Arbitrary JSON the customer stores against the client. Vaquill never reads it.
When the client was created (RFC 3339). Absent on a small number of rows that predate the column default.
"2026-08-19T14:32:10Z"
When the client was last modified (RFC 3339).
"2026-08-19T14:32:10Z"
Was this page helpful?

