π Invoicing API
Create invoices & contracts programmatically from your saved templates β for integrations, portals, and automated onboarding.
1. Get an API key
Keys are generated in the app and shown exactly once β store them somewhere safe (a password manager, secret store, or environment variable).
- Open Invoicing β Settings β π Invoicing API
- Give the key a name (e.g. "Production server") and click Generate Key
- Copy the key β it starts with
saflio_sk_β you won't see it again
2. Authenticate
Send your key as a Bearer token in the Authorization header on every request:
Authorization: Bearer saflio_sk_<your-key> The API lives on the same host as the app's API. Use the environment that matches your account:
- Development:
https://api.saflio.dev - Production:
https://api.saflio.app
3. List your templates
Every contract is created from a template. List what's available β Saflio defaults plus templates you've saved:
/v1/templatescurl -H "Authorization: Bearer $SAFLIO_API_KEY" \
https://api.saflio.dev/v1/templates Response β each item includes the templateKey you'll use to create a contract, plus its sections and fill-in fields:
{
"items": [
{
"templateKey": "managed-network",
"name": "Managed Network Maintenance",
"title": "MANAGED NETWORK MAINTENANCE AGREEMENT",
"scope": "default",
"sections": [ { "title": "1. SCOPE OF SERVICES", "body": "β¦", "subsections": [β¦] } ],
"fillables": { "businessHours": {"label": "Business Hours", "def": "MonβFri, 9:00β17:00 CT"} }
}
]
} 4. Create a contract
Send the template key plus the details for this specific contract. You can pass an existing clientId, or include a client object and one will be created for you.
/v1/contractscurl -X POST https://api.saflio.dev/v1/contracts \
-H "Authorization: Bearer $SAFLIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateKey": "managed-network",
"client": { "name": "Big Air", "email": "[email protected]", "company": "Big Air LLC" },
"fee": 1500,
"currency": "USD",
"effectiveDate": "2026-09-01",
"title": "Big Air Maintenance Agreement",
"fillables": { "governingLaw": "Illinois", "businessHours": "MonβFri, 8:00β17:00 CT" }
}' Request body
| Field | Type | Required | Description |
|---|---|---|---|
templateKey | string | β | The template to build from (from /v1/templates) |
client or clientId | object / string | β | Client details to create, or the id of an existing client you own |
fee | number | β | Monthly fee (defaults to 0) |
currency | string | β | USD, PHP, or JMD (defaults to USD) |
effectiveDate | string | β | YYYY-MM-DD effective date |
title | string | β | Agreement title (defaults to the template's title) |
fillables | object | β | Values for the template's fill-in fields (business hours, governing law, β¦) |
sections | array | β | Optional: override the template's sections entirely |
subscriptionId | string | β | Link to an existing subscription (starts billing on signature) |
Response β the new contract (status draft):
{
"ok": true,
"id": "abc123β¦",
"status": "draft",
"title": "Big Air Maintenance Agreement",
"templateKey": "managed-network",
"client": "β¦client idβ¦",
"fee": 1500,
"currency": "USD",
"effectiveDate": "2026-09-01"
} 5. List & fetch contracts
/v1/contractscurl -H "Authorization: Bearer $SAFLIO_API_KEY" \
https://api.saflio.dev/v1/contracts Returns your contracts, newest first, with status, fee, and template key for each.
/v1/contracts/:idcurl -H "Authorization: Bearer $SAFLIO_API_KEY" \
https://api.saflio.dev/v1/contracts/abc123 Returns the full contract, including content with all sections, sub-sections, and applied fill-in values.
6. Errors
| Code | Meaning |
|---|---|
400 | Bad request β missing or invalid fields (e.g. no templateKey) |
401 | Invalid or revoked API key |
403 | Not allowed β e.g. a clientId that isn't yours |
404 | Template or contract not found |
500 | Something went wrong on our side β retry with backoff |
Errors return JSON: {"error": "message"}
7. Managing keys
- Keys are per-user β each key acts as the account that generated it.
- Revoke a key anytime in Invoicing β Settings β π Invoicing API; it stops working immediately.
- Generate separate keys per integration so you can revoke them independently.