What it is
The Nemphi API is a JSON REST API at https://api.nemphi.com. Every capability in the product (customers, e-invoicing, collections, accounting, marketing, projects and the agents) is a tool with a name, such as invoices.list, and a JSON input schema.
GET /v1/tools lists the tools your credential reaches and POST /v1/tools/{name}:invoke runs one. There are no side doors: every call goes through the same pipeline as the app, with your role's permissions, the workspace's autonomy policies, approvals and the action ledger.
The full description, one operation per tool with its schema, is at https://www.nemphi.com/openapi.json (OpenAPI 3.1).
Authentication and scopes
Send the credential as Authorization: Bearer …. There are two kinds.
OAuth 2.1. For applications acting for a person: authorization code with PKCE (S256), dynamic client registration at https://api.nemphi.com/oauth/register or Client ID Metadata Documents. Access tokens last 1 hour and refresh tokens 30 days. The metadata is at https://api.nemphi.com/.well-known/oauth-authorization-server (RFC 8414) and https://api.nemphi.com/.well-known/oauth-protected-resource (RFC 9728).
| Scope | What it allows |
|---|---|
tools:read |
Read tools only. Nothing changes in the workspace. |
tools |
Every tool the granting member's role reaches, reads and writes. What the workspace holds for approval still waits for a person. |
sites.login |
Sign a visitor in to a site hosted on Nemphi. Identity only, no tools. |
sites.edit |
Edit the workspace's sites through the Studio's tools (sites.*). |
Ask for the smallest scope that does the job. The OpenAPI specification names, on every operation, the scope that reaches it.
API key. For your own programs: create one in Nemphi under Developers › API keys. It starts with nk_, carries the role you give it, and can be narrowed to tool patterns such as invoices.% or %:read.
Endpoints
| Method and path | What it does | Authentication |
|---|---|---|
GET /v1/tools |
Lists the tools the credential reaches, with their risk class and input schema. | tools:read, tools or a key |
POST /v1/tools/{name}:invoke |
Runs a tool. The body is its JSON input. | tools:read for reads, tools for the rest, or a key |
POST /v1/auth/agent-signup |
An AI agent opens an account and workspace for the person it works for. | None |
POST /mcp |
The MCP server. | tools:read, tools or a key |
GET /healthz |
Whether the API is serving. | None |
Optional headers: Idempotency-Key replays the first answer when you send the same call again, and X-Tenant-Id names the workspace (a key or token already belongs to exactly one).
Examples
List the tools your key reaches:
curl https://api.nemphi.com/v1/tools \
-H "Authorization: Bearer $NEMPHI_API_KEY"
Run one:
curl -X POST https://api.nemphi.com/v1/tools/invoices.list:invoke \
-H "Authorization: Bearer $NEMPHI_API_KEY" \
-H "content-type: application/json" \
-H "Idempotency-Key: 4f1c2a9e-invoices-list" \
-d '{"status": "draft"}'
The answer carries the tool's name and its output:
{
"tool": "invoices.list",
"output": { "invoices": [ … ] }
}
From TypeScript, the @nemphi/sdk SDK does the same with nemphi.invoke("invoices.list", { status: "draft" }).
Responses and errors
- 200: the tool ran;
outputis its result. - 202
pending_approval: in a workspace an agent opened, the call waits for the owner. It carries the approval's id; relay your user's answer with theapprovals.decidetool. - 4xx: a refusal with the body
{"error", "code"}.codeis stable anderroris a sentence for a person.
{
"error": "invoices.list: invalid input: status must be one of draft, posted, void",
"code": "invalid_input",
"field": "status"
}
| Code | Status | Meaning |
|---|---|---|
unauthenticated |
401 | The credential is missing, expired or revoked. |
insufficient_scope |
403 | The credential's scopes do not reach that endpoint. |
approval_required |
403 | The call waits for a person's approval in Nemphi's inbox. |
policy_denied |
403 | The credential's scopes, the role or the workspace's policies do not allow that tool. |
unknown_tool |
404 | There is no tool by that name. |
idempotency_conflict |
409 | That Idempotency-Key was already used with a different input. |
body_too_large |
413 | The input exceeds the tool's limit. |
invalid_input |
422 | An argument does not fit the schema; field names it. |
rate_limited |
429 | Too many requests; wait and retry. |
Machine-readable resources
- OpenAPI specification: every tool as an operation, with its schema and scope.
- Authorization server metadata (RFC 8414) and protected resource metadata (RFC 9728), with
scopes_supported. - API catalog (RFC 9727).
- llms.txt: the site's map for language models, with the guide for an agent opening an account.
- MCP server: the same pipeline for AI assistants.
Questions? Write to [email protected].