Coming Soon

Need to push / pull data that isn't listed yet? No problem! Contact our support team & we'll jump right on it.

Using MuleSoft, Redoc, or other Swagger Tools?

Firm App provides an OpenAPI 3.1 spec in both JSON and YAML formats:

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('', {
    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());


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('', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    id: 'absdfjkfj',
    endpointId: 'getUser',
    apiVersion: '1',
}).then(f => f.json());


In the example above, all request/response data is contained in the request/response body.


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('Firm App error:');
  console.log('Error (not from firm app): ', e);


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


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 »