0.05 — API
The Zerosoft API.
Zero friction.
All products expose the same style of API: REST, JSON and personal keys. If the dashboard can do it, your code can do it.
Base URL
https://zerosoft.ai/api/v1Authentication
Every request needs an API key, sent as a Bearer token. For browser sessions the Google OAuth flow creates the session cookie.
Authorization: Bearer zs_live_9f3k...Create keys in Dashboard → Settings → API keys. A key is shown exactly once — copy it and store it like a password. Each key allows 100 requests per minute.
Google OAuth sign-in
/api/auth/signin/googleRedirect the user to start the Google OAuth flow. After success they return to the app with a session cookie.
curl -X GET "https://zerosoft.ai/api/auth/signin/google" \
-H "Authorization: Bearer zs_live_9f3k..."Links
Create, list, update and measure short links.
Create a link
/api/v1/linksCreates a short link. slug is optional — leave it out and we generate one.
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Destination URL. |
slug | string | No | Custom short slug. |
title | string | No | Human-friendly title. |
tags | string[] | No | Array of tag strings. |
curl -X POST "https://zerosoft.ai/api/v1/links" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"url": "https://zerosoft.ai/blog/software-is-dead",
"slug": "manifesto",
"title": "The manifesto",
"tags": [
"launch",
"blog"
]
}'Request
{
"url": "https://zerosoft.ai/blog/software-is-dead",
"slug": "manifesto",
"title": "The manifesto",
"tags": [
"launch",
"blog"
]
}Response · 201
{
"id": "lnk_9f3ka2",
"slug": "manifesto",
"short_url": "https://zs.ai/manifesto",
"url": "https://zerosoft.ai/blog/software-is-dead",
"title": "The manifesto",
"tags": [
"launch",
"blog"
],
"created_at": "2026-07-14T18:22:41Z"
}List links
/api/v1/linksYour links, newest first. Paginate with page and pageSize (max 100).
| Name | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number. |
pageSize | integer | No | Items per page (max 100). |
curl -X GET "https://zerosoft.ai/api/v1/links" \
-H "Authorization: Bearer zs_live_9f3k..."Response · 200
{
"links": [
{
"id": "lnk_9f3ka2",
"slug": "manifesto",
"short_url": "https://zs.ai/manifesto",
"url": "https://zerosoft.ai/blog/software-is-dead",
"title": "The manifesto",
"tags": [
"launch",
"blog"
],
"clicks": 4812,
"archived": false,
"created_at": "2026-07-14T18:22:41Z"
}
],
"total": 48
}Delete a link
/api/v1/links/{id}Archive or delete a link by id.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Link id. |
curl -X DELETE "https://zerosoft.ai/api/v1/links/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."Response · 200
{
"ok": true
}Update a link
/api/v1/links/{id}Update any writable field of a link.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Link id. |
url | string | No | Destination URL. |
slug | string | No | Custom short slug. |
title | string | No | Human-friendly title. |
tags | string[] | No | Array of tag strings. |
archived | boolean | No | Archive flag. |
curl -X PATCH "https://zerosoft.ai/api/v1/links/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"title": "The manifesto — updated"
}'Request
{
"title": "The manifesto — updated"
}Response · 200
{
"ok": true
}Link stats
/api/v1/links/{id}/statsClick totals and a per-day breakdown for one link.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Link id. |
curl -X GET "https://zerosoft.ai/api/v1/links/{id}/stats" \
-H "Authorization: Bearer zs_live_9f3k..."Response · 200
{
"slug": "manifesto",
"total": 4812,
"byDay": [
{
"date": "2026-07-15",
"count": 412
},
{
"date": "2026-07-16",
"count": 388
},
{
"date": "2026-07-17",
"count": 441
}
]
}CRM — Contacts
People and leads.
List contacts
/api/v1/crm/contactsList contacts. Filters: q, page, pageSize (max 100).
| Name | Type | Required | Description |
|---|---|---|---|
q | string | No | Search query. |
page | integer | No | Page number. |
pageSize | integer | No | Items per page (max 100). |
curl -X GET "https://zerosoft.ai/api/v1/crm/contacts" \
-H "Authorization: Bearer zs_live_9f3k..."Response · 200
{
"rows": [
{
"id": "b1f47ac2-…",
"first_name": "Ana",
"last_name": "Garcia",
"email": "ana@kallpa.co",
"lifecycle_stage": "sql",
"created_at": "2026-07-18 10:04:11"
}
],
"total": 142,
"page": 1,
"pageSize": 10
}Create a contact
/api/v1/crm/contactsCreate a new contact.
| Name | Type | Required | Description |
|---|---|---|---|
first_name | string | No | First name. |
last_name | string | No | Last name. |
email | string | No | Email address. |
lifecycle_stage | string | No | Lifecycle stage (lead, sql, opportunity, customer). |
curl -X POST "https://zerosoft.ai/api/v1/crm/contacts" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"first_name": "Ana",
"last_name": "Garcia",
"email": "ana@kallpa.co",
"lifecycle_stage": "sql"
}'Request
{
"first_name": "Ana",
"last_name": "Garcia",
"email": "ana@kallpa.co",
"lifecycle_stage": "sql"
}Response · 201
{
"id": "b1f47ac2-…",
"first_name": "Ana",
"last_name": "Garcia",
"email": "ana@kallpa.co",
"lifecycle_stage": "sql",
"created_at": "2026-07-18 10:04:11"
}Get a contact
/api/v1/crm/contacts/{id}Read one contact by id.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Record id. |
curl -X GET "https://zerosoft.ai/api/v1/crm/contacts/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."Update a contact
/api/v1/crm/contacts/{id}Update any property of a contact.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Record id. |
first_name | string | No | First name. |
last_name | string | No | Last name. |
email | string | No | Email address. |
curl -X PATCH "https://zerosoft.ai/api/v1/crm/contacts/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"lifecycle_stage": "opportunity"
}'Request
{
"lifecycle_stage": "opportunity"
}CRM — Companies
Organizations and accounts.
List companies
/api/v1/crm/companiesList companies. Filters: q, page, pageSize.
| Name | Type | Required | Description |
|---|---|---|---|
q | string | No | Search query. |
page | integer | No | Page number. |
pageSize | integer | No | Items per page (max 100). |
curl -X GET "https://zerosoft.ai/api/v1/crm/companies" \
-H "Authorization: Bearer zs_live_9f3k..."Create a company
/api/v1/crm/companiesCreate a new company.
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Company name. |
domain | string | No | Domain name. |
industry | string | No | Industry. |
curl -X POST "https://zerosoft.ai/api/v1/crm/companies" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"name": "Norte Labs",
"domain": "nortelabs.co",
"industry": "Software"
}'Request
{
"name": "Norte Labs",
"domain": "nortelabs.co",
"industry": "Software"
}Get a company
/api/v1/crm/companies/{id}Read one company by id.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Record id. |
curl -X GET "https://zerosoft.ai/api/v1/crm/companies/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."Update a company
/api/v1/crm/companies/{id}Update any property of a company.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Record id. |
name | string | No | Company name. |
domain | string | No | Domain name. |
curl -X PATCH "https://zerosoft.ai/api/v1/crm/companies/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"industry": "Cloud infrastructure"
}'Request
{
"industry": "Cloud infrastructure"
}CRM — Deals
Opportunities and pipelines.
List deals
/api/v1/crm/dealsList deals. Filter: pipelineId.
| Name | Type | Required | Description |
|---|---|---|---|
pipelineId | string | No | Pipeline id. |
q | string | No | Search query. |
page | integer | No | Page number. |
pageSize | integer | No | Items per page (max 100). |
curl -X GET "https://zerosoft.ai/api/v1/crm/deals" \
-H "Authorization: Bearer zs_live_9f3k..."Create a deal
/api/v1/crm/dealsCreate a deal in a pipeline stage.
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Deal name. |
amount | number | No | Deal amount. |
currency | string | No | Currency code. |
stage_id | string | Yes | Stage id. |
curl -X POST "https://zerosoft.ai/api/v1/crm/deals" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"name": "Norte Labs — New business",
"amount": 24000,
"currency": "USD",
"stage_id": "{stage_id}"
}'Request
{
"name": "Norte Labs — New business",
"amount": 24000,
"currency": "USD",
"stage_id": "{stage_id}"
}Get a deal
/api/v1/crm/deals/{id}Read one deal by id.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Record id. |
curl -X GET "https://zerosoft.ai/api/v1/crm/deals/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."Update a deal
/api/v1/crm/deals/{id}Update amount, stage or dates.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Record id. |
name | string | No | Deal name. |
amount | number | No | Deal amount. |
stage_id | string | No | Stage id. |
curl -X PATCH "https://zerosoft.ai/api/v1/crm/deals/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"amount": 28000
}'Request
{
"amount": 28000
}CRM — Tasks
Activities and follow-ups.
List tasks
/api/v1/crm/tasksList tasks. bucket: overdue, today, upcoming, done.
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | No | Filter bucket: overdue, today, upcoming, done. |
page | integer | No | Page number. |
pageSize | integer | No | Items per page (max 100). |
curl -X GET "https://zerosoft.ai/api/v1/crm/tasks" \
-H "Authorization: Bearer zs_live_9f3k..."Create a task
/api/v1/crm/tasksCreate a task, optionally linked to a record.
| Name | Type | Required | Description |
|---|---|---|---|
subject | string | Yes | Task subject. |
due_at | string (ISO) | No | Due date in ISO format. |
contact_id | string | No | Linked contact id. |
company_id | string | No | Linked company id. |
deal_id | string | No | Linked deal id. |
curl -X POST "https://zerosoft.ai/api/v1/crm/tasks" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"subject": "Follow-up call",
"due_at": "2026-07-25T15:00:00Z",
"deal_id": "{deal_id}"
}'Request
{
"subject": "Follow-up call",
"due_at": "2026-07-25T15:00:00Z",
"deal_id": "{deal_id}"
}Update a task
/api/v1/crm/tasks/{id}Edit or complete a task.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Record id. |
subject | string | No | Task subject. |
done | boolean | No | Mark as done. |
curl -X PATCH "https://zerosoft.ai/api/v1/crm/tasks/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"done": true
}'Request
{
"done": true
}CRM — Pipelines & stages
Sales pipelines and their stages.
List pipelines
/api/crm/pipelinesList pipelines with their stages.
curl -X GET "https://zerosoft.ai/api/crm/pipelines" \
-H "Authorization: Bearer zs_live_9f3k..."Create a pipeline
/api/crm/pipelinesCreate a new pipeline.
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Pipeline name. |
curl -X POST "https://zerosoft.ai/api/crm/pipelines" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"name": "Sales"
}'Request
{
"name": "Sales"
}List stages
/api/crm/pipelines/{id}/stagesList stages of a pipeline.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Pipeline id. |
curl -X GET "https://zerosoft.ai/api/crm/pipelines/{id}/stages" \
-H "Authorization: Bearer zs_live_9f3k..."Create a stage
/api/crm/pipelines/{id}/stagesCreate a stage inside a pipeline.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Pipeline id. |
name | string | Yes | Stage name. |
probability | integer | No | Win probability (0-100). |
curl -X POST "https://zerosoft.ai/api/crm/pipelines/{id}/stages" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"name": "Proposal",
"probability": 50
}'Request
{
"name": "Proposal",
"probability": 50
}Teams
Invite, accept and switch workspaces.
Invite to team
/api/teams/invitesInvite an email to join a team.
| Name | Type | Required | Description |
|---|---|---|---|
teamId | string | Yes | Team id. |
email | string | Yes | Email to invite. |
curl -X POST "https://zerosoft.ai/api/teams/invites" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"teamId": "{team_id}",
"email": "teammate@company.com"
}'Request
{
"teamId": "{team_id}",
"email": "teammate@company.com"
}Response · 201
{
"invite": {
"id": "inv_…",
"token": "…"
},
"url": "https://zerosoft.ai/en/invite/…"
}Accept invite
/api/teams/acceptAccept an invite by token.
| Name | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Invite token. |
curl -X POST "https://zerosoft.ai/api/teams/accept" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"token": "{invite_token}"
}'Request
{
"token": "{invite_token}"
}Response · 200
{
"ok": true,
"team": {
"id": "{team_id}",
"name": "Norte Labs"
}
}Switch team
/api/teams/switchSwitch active workspace. Use teamId: null for the personal workspace.
| Name | Type | Required | Description |
|---|---|---|---|
teamId | string | null | No | Team id or null for the personal workspace. |
curl -X POST "https://zerosoft.ai/api/teams/switch" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"teamId": "{team_id}"
}'Request
{
"teamId": "{team_id}"
}Response · 200
{
"ok": true
}Docs
Pages and wikis.
List pages
/api/docs/pagesList docs pages.
curl -X GET "https://zerosoft.ai/api/docs/pages" \
-H "Authorization: Bearer zs_live_9f3k..."Response · 200
{
"rows": [
{
"id": "page_…",
"title": "Wiki home",
"parent_id": null,
"updated_at": "2026-07-18T12:00:00Z"
}
]
}Create page
/api/docs/pagesCreate a new docs page.
| Name | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Page title. |
parent_id | string | No | Parent page id. |
content | DocsBlock[] | No | Page content blocks. |
curl -X POST "https://zerosoft.ai/api/docs/pages" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"title": "Onboarding",
"parent_id": null,
"content": []
}'Request
{
"title": "Onboarding",
"parent_id": null,
"content": []
}Get page
/api/docs/pages/{id}Read one page by id.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Page id. |
curl -X GET "https://zerosoft.ai/api/docs/pages/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."Update page
/api/docs/pages/{id}Update title, content or archive a page.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Page id. |
title | string | No | Page title. |
content | DocsBlock[] | No | Page content blocks. |
archived | boolean | No | Archive flag. |
curl -X PATCH "https://zerosoft.ai/api/docs/pages/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."
-H "Content-Type: application/json" \
-d '{
"title": "Onboarding v2"
}'Request
{
"title": "Onboarding v2"
}Delete page
/api/docs/pages/{id}Delete a page by id.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Page id. |
curl -X DELETE "https://zerosoft.ai/api/docs/pages/{id}" \
-H "Authorization: Bearer zs_live_9f3k..."Response · 200
{
"ok": true
}