Skip to content

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

  1. In Karya Falak, an owner or admin turns on API and Zapier in Settings > Features.
  2. Settings > API and Zapier > New API key: give it a name and choose Read only or Read and add.
  3. 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

MethodPathWhat it doesNeeds
GET/api/v1/meThe key and its organisation
Read
GET/api/v1/contactsList contacts
Read
POST/api/v1/contactsAdd a contact
Read and add
GET/api/v1/contacts/{id}Get a contact
Read
GET/api/v1/ticketsList tickets
Read
POST/api/v1/ticketsAdd 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}/notesAdd a note for the team
Read and add
GET/api/v1/messagesList customer messages
Read
GET/api/v1/quotesList quotes
Read
Quotes
GET/api/v1/quotes/{id}Get a quote
Read
Quotes
POST/api/v1/tickets/{id}/quotesStart a draft quote on a ticket
Read and add
Quotes
GET/api/v1/visitsList visits
Read
Visits
GET/api/v1/visits/{id}Get a visit
Read
Visits
POST/api/v1/tickets/{id}/visitsBook a visit on a ticket
Read and add
Visits
GET/api/v1/invoicesList invoices
Read
Invoicing
GET/api/v1/invoices/{id}Get an invoice
Read
Invoicing
GET/api/v1/paymentsList payments
Read
Invoicing
GET/api/v1/payments/{id}Get a payment
Read
Invoicing
POST/api/v1/hooksSubscribe 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.