Integration
The API
Anything you already run can read your CRM without a bespoke integration and without a password. A scoped key, a version in the path, and a machine-readable description that cannot describe an endpoint that does not exist.
The claim
Treasury has a public API with scoped keys, so anything you run can read your CRM without a bespoke integration.
Today
What exists now
- Version in the path
- The base path is /api/v1. A version you cannot see in a log line or in a curl command is a version nobody debugs correctly.
- Scoped keys
- Scopes are read and write over leads, companies, deals, activities, tasks, bookings and units. There is no hierarchy, so a write scope does not imply a read scope.
- Shown once
- The secret is displayed at creation and never again, and only a digest is stored. A key a vendor can show you again is a key the vendor is storing.
- Revoked immediately
- Nothing about a key is cached, so revoking one takes effect on the very next request rather than within a minute.
- An OpenAPI document
- Generated from the same schemas the routes validate with, so it cannot drift from the product. It needs no key.
- Cursor pagination
- Never offset. Rows arrive from webhooks while you are walking a list, and an offset silently repeats and skips without telling you.
- A filter tree
- The same tree the product's own saved filters use, over your own custom fields as well as the built-in ones. The account boundary is applied around the whole tree and no operator can reach it.
- Read only, honestly
- Create and update exist for leads behind a flag that is off, and with it off those endpoints answer 404. That is the truth of the deployment rather than a hint about a roadmap.
The boundary
Another account's record is a 404
Ask for a record belonging to somebody else and the answer is 404, never 403. A 403 confirms that the id exists, and ids here are dense serials, so that difference is an enumeration oracle.
Every response carries a request id, in the body and in a header, and it is written to our log with the outcome. Quote it and we can tell you exactly what happened.
Working with it
Rate limits you can see
Three ceilings apply: per address, per key and per account. The per-key one is the one you can act on, and it is reported on every response along with what is left and when it resets. A refusal carries the number of seconds to wait.
On the write endpoints, an idempotency key replays the first response instead of writing twice, and reusing that key for a different request is refused rather than quietly replayed.
Asked and answered
Questions
- Can I write leads over the API?
- Not on the current deployment. The write endpoints exist behind a flag that is off, and while it is off they answer 404 rather than pretending.
- How do I get a key?
- An owner creates one in settings, choosing the scopes it carries. The secret is shown once at creation and is not recoverable.
- Is there a machine-readable description?
- Yes, an OpenAPI document at /api/v1/openapi.json, generated from the code rather than written by hand, and it needs no key.
- Does the API cross brands?
- No. A key belongs to one workspace and the account boundary is applied around every query, so a key for one brand cannot read another brand's rows.
Request access
Tell us how many brands you run and who needs to see them. We will walk you through the system with your names in it, not ours.
We reply within one working day. Already a customer? Sign in at app.treasurycrm.com.