Developers
The Karya Falak API
Read and add to your organisation from your own scripts and Zapier, and be told the moment something happens: a new message, a ticket moved, a quote accepted, an invoice paid.
Get a key
- In Karya Falak, an owner or admin turns on API and Zapier in Settings > Features.
- Settings > API and Zapier > New API key: give it a name and choose Read only or Read and add.
- Copy the key. It is shown once; we keep only a fingerprint of it. Revoke it there whenever you like.
- Read only: lists and gets contacts, tickets and messages, and quotes, visits, invoices and payments where those parts of the product are on.
- Read and add: also adds contacts, tickets, notes for the team, draft quotes and visits, with the same checks as a person, and subscribes webhooks (Zapier triggers).
- Message text: off unless you ask for it. Without it, message bodies, notes and comment text, and the title of a ticket opened from a conversation, come back as null. One-time codes never come back.
- A key works as the owner or admin who made it, never above an admin, and stops when they are no longer one.
Sign each request
curl https://api.karyafalak.com/api/v1/tickets?limit=10 \
-H "Authorization: Bearer kf_live_..."curl https://api.karyafalak.com/api/v1/contacts \
-H "Authorization: Bearer kf_live_..." \
-H "Content-Type: application/json" \
-d '{"display_name": "Rita Cole", "email": "rita@example.com"}'Endpoints
| Method | Path | What it does | Needs |
|---|---|---|---|
| GET | /api/v1/me | The key and its organisation | Read |
| GET | /api/v1/contacts | List contacts | Read |
| POST | /api/v1/contacts | Add a contact | Read and add |
| GET | /api/v1/contacts/{id} | Get a contact | Read |
| GET | /api/v1/tickets | List tickets | Read |
| POST | /api/v1/tickets | Add a ticket (on Incoming unless a board is given) | Read and add |
| GET | /api/v1/tickets/{id} | Get a ticket | Read |
| POST | /api/v1/tickets/{id}/notes | Add a note for the team | Read and add |
| GET | /api/v1/messages | List customer messages | Read |
| GET | /api/v1/quotes | List quotes | Read Quotes |
| GET | /api/v1/quotes/{id} | Get a quote | Read Quotes |
| POST | /api/v1/tickets/{id}/quotes | Start a draft quote on a ticket | Read and add Quotes |
| GET | /api/v1/visits | List visits | Read Visits |
| GET | /api/v1/visits/{id} | Get a visit | Read Visits |
| POST | /api/v1/tickets/{id}/visits | Book a visit on a ticket | Read and add Visits |
| GET | /api/v1/invoices | List invoices | Read Invoicing |
| GET | /api/v1/invoices/{id} | Get an invoice | Read Invoicing |
| GET | /api/v1/payments | List payments | Read Invoicing |
| GET | /api/v1/payments/{id} | Get a payment | Read Invoicing |
| POST | /api/v1/hooks | Subscribe an address to one event (REST hooks, as Zapier uses them) | Read and add |
| DELETE | /api/v1/hooks/{id} | Unsubscribe | Read and add |
Lists, limits and errors
- Lists are newest first, 50 at a time (up to 100 with limit). When there is more, next_cursor is set: pass it back as cursor.
- Each key may make 120 requests a minute. Past that the answer is 429, with Retry-After in seconds.
- Errors are JSON: { "code", "message", "details" }. 401 is a missing, wrong or revoked key; 403 insufficient_scope or module_disabled; 404 not found, including anything of another organisation.
Webhooks
- In Settings > API and Zapier > Add webhook, give a public https address and the events to send. The signing secret is shown once.
- Each event is a POST of JSON: id, type, created_at, organisation_id and data, the record as the API returns it. ticket.moved adds previous, the column it left.
- Answer with any 2xx. Anything else is tried again after 1 minute, 5 minutes, 30 minutes, 2, 6, 12 and 24 hours; an address that fails 25 times in a row is switched off, and you can turn it back on there.
- The same event can arrive twice: Kf-Event-Id is the same on every try, so keep the ones you have seen.
Events
contact.created
ticket.created
ticket.moved
message.received
quote.sent
quote.accepted
quote.declined
quote.changes_requested
invoice.issued
invoice.paid
visit.booked
visit.done
Check a webhook is ours
The Kf-Signature header is t=<unix seconds>,v1=<hex>: HMAC-SHA256 with your signing secret over the timestamp, a full stop and the raw body. Check it over the bytes you received, before parsing them, in constant time, and refuse a timestamp more than five minutes old.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function isFromKaryaFalak(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = createHmac('sha256', secret).update(`${t}.`).update(rawBody).digest();
const given = Buffer.from(parts.v1 ?? '', 'hex');
return given.length === expected.length && timingSafeEqual(given, expected);
}Zapier
- The Karya Falak Zapier app is private for now: ask us for its invite link from Support.
- Instant triggers: new contact, new ticket, ticket moved, new message from a customer, quote sent, quote accepted, changes asked for on a quote, invoice paid and visit booked.
- Actions: add a contact, add a ticket, add a note, start a draft quote and book a visit.
- Connect it with an API key from Settings. Each Zap’s trigger appears in Settings as a webhook made by that key, and stops if the key is revoked.
OpenAPI
The whole API, as OpenAPI 3.1, to read or to load into a tool.