Fetching Data
Firm App's API follows a simple JSON-RPC style where requests are made over an HTTPS connection using a JSON format.
The RPC style means that both the request and its response are fully conveyed in the request body and response body. This means it is not necessary to examine the external data such as HTTP request method, query string, url parameters, and HTTP response status codes to interpret the data. It also eliminates potential data leaks from logging urls, request methods, query strings, etc.
Making a Request
All endpoints require the same request format which is a POST request with a JSON body. Here is a simple example in NodeJS:
const res = await fetch('https://api.firm.app/getUser', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY_GOES_HERE', 'X-Api-Secret': 'YOUR_API_SECRET_GOES_HERE', 'X-Api-Version': '1' }, body: JSON.stringify({id: 'absdfjkfj'}) }).then(f => f.json()); console.log(res.user.name);
Be sure to swap in your API Tokens (learn more).
If you wish to go all in on RPC data encapsulation, then the API Key, API Secret, API Version, and
even the operationId (e.g. getUser) can be provided through the request body by using the execute
endpoint:
const res = await fetch('https://api.firm.app/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'absdfjkfj', endpointId: 'getUser', apiKey: 'YOUR_API_KEY_GOES_HERE', apiSecret: 'YOUR_API_SECRET_GOES_HERE', apiVersion: '1', }) }).then(f => f.json()); console.log(res.user.name);
In the example above, all request/response data is contained in the request/response body.
Versioning
The X-API-Version
header (or apiVersion
body parameter) are both optional and defaulted to 1
.
Currently, version 1
is the only version available. While additional versions may be added if there is an unavoidable breaking change, the primary
goal is "What worked yesterday should work tomorrow." [1]
This means changes will come in the form of additional properties and endpoints, redundant fields, and redundant query parameters.
Receiving the Response
All responses from the Firm App API will have a status code 200
with a content type of application/json
. The JSON data will
include ok=true
for success and ok=false
for an error (will also include an error object).
If a response does not have a 200 status code, then it is not a Firm App API response
which means that it may not be JSON.
For the typescript-interfacy-java-nerds out there (like me), here's the spec for all responses:
interface IError { code: string; message: string; status: number; } interface IMeta { requestId: string; duration: number; // milliseconds rateLimitRemaining: number; rateLimitLimit: number; } interface IResponse { ok: boolean; meta: IMeta; error?: IError; [key: string]: any; }
Here's an example of how you might handle errors in NodeJS:
try { const req = await fetch(...); const res = await req.json(); if (req.ok) { console.log('Success!'); console.log(res.user.name); }else{ console.log('Firm App error:'); console.log(res.error.code); console.log(res.error.message); } }catch(e){ console.log('Error (not from firm app): ', e); }
META
You may have noticed above that all responses also include a meta
field. This includes information
like the request id, processing duration (in milliseconds), and rate limiting status. As the API matures, fields
may be added or removed.
The meta data is also available in the response headers.
X-Request-Id: sjdf267f8yd3saeihfhr X-Response-Duration: 25 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 93
SSL / TLS
Firm App only allows HTTPS connections over TLS 1.2 (TLS 1.0, 1.1 and SSL 1,2,3 have known vulnerabilities). For most clients, this is not an issue.
Next up, learn about Endpoints »