Skip to main content
Use GraphQL bulk operations when your integration needs to read a larger set of Firmhouse records than a normal paginated API request should handle at once. A bulk operation runs in the background and gives you a JSONL download URL when the operation completes. This is useful for exports, data warehouse syncs, reporting jobs, and other integrations where you want to process many records outside the request-response cycle of the GraphQL API. For large exports, use bulk operations instead of increasing normal query size until the request reaches GraphQL query complexity or timeout limits.

Requirements

  • A Firmhouse API access token with write access to start the bulk operation.
  • Read access to the data selected by the query.
  • One active bulk operation at a time per project.

Start a bulk operation

Call bulkOperationRunQuery with the GraphQL query you want Firmhouse to run.
Always request and check errors in the response. Firmhouse can return query parse or validation messages there, for example when the query is malformed or uses an unsupported bulk operation shape. If errors is not empty, bulkOperation will be null and no background operation was created. When the operation is accepted, the response contains a bulk operation with status CREATED. Store the id; you need it to check the operation later.

Query rules

Bulk operation queries use the same Firmhouse GraphQL schema as regular API requests, but the top-level query shape is restricted so the result can be exported predictably. Your query must:
  • Be a query operation, not a mutation or subscription.
  • Select exactly one top-level field.
  • Use a top-level connection field, such as a field that returns nodes or edges { node { ... } }.
  • Leave top-level pagination arguments to Firmhouse. Do not pass first, last, before, or after on the top-level connection.
  • Not select more than five total connection fields in the query, including nested connections.
  • Not select nested connections more than two connection levels below the top-level connection.
This works:
This does not work because it passes pagination arguments on the top-level connection:
Bulk operations export all records from the top-level connection. If you select a nested connection, that nested connection follows the normal GraphQL API pagination rules. For example, it returns up to the default page size unless you pass supported pagination arguments for that nested field. A bulk operation does not automatically walk through every page of nested connections.

Check the status

Use the bulkOperation query with the ID from bulkOperationRunQuery.
Bulk operations can have these statuses:
  • CREATED: the operation was created and is waiting to start.
  • RUNNING: Firmhouse is reading the data.
  • COMPLETED: the JSONL result file is ready and url is available.
  • FAILED: the operation could not complete. Check errorCode.

Download the JSONL result

When the status is COMPLETED, download the file from url. The file is JSONL, also known as newline-delimited JSON. Each line is one complete JSON object from the selected connection:
JSONL is a good fit for bulk exports because the file does not need to be parsed as one large JSON array. Your integration can read one line, parse that line as JSON, process or store the record, and then move to the next line. This matters for larger exports. Avoid loading the entire file into memory before parsing it. Instead, stream the response or downloaded file line by line. For example, in Node.js you can process a downloaded file with a line reader:
The same pattern applies in other languages: open the file as a stream, read one line at a time, parse each line, and handle failures in a way that lets you retry from your own last processed record.

Use the finished webhook

Instead of polling until completion, you can subscribe to the graphql_bulk_operation_finished outgoing webhook event. Create this webhook before you start the bulk operation if your integration should continue automatically when the result file is ready.
  1. In Firmhouse, go to Apps.
  2. Scroll to Webhooks and click Configure.
  3. Click New outgoing webhook.
  4. Enter a name, such as GraphQL bulk operation finished.
  5. Enter the endpoint URL in your own system that should receive the completion notification.
  6. Set Content type to JSON.
  7. Select the GraphQL bulk operation finished event.
  8. Add a JSON template that includes the bulk operation fields your integration needs.
  9. Click Save.
Recommended template:
Firmhouse sends this webhook after a bulk operation reaches a final state. Use it to trigger the download step in your own system. If the operation failed, inspect status and error_code before retrying or starting a new operation. The url value is only available when the operation completed successfully. Your webhook handler should check status before trying to download the JSONL file.