FeaturesPricingAboutArticlesDocumentation
Developers

API, SDK, MCP and webhooks.

Developer PlatformQuickstartAuthenticationAPI ReferenceSDKMCPWebhooksErrorsPaginationRate LimitsIdempotencyChangelogMigration and Versioning Policy
Raw API docsOpenAPI YAMLAsyncAPI YAML
  1. Home
  2. /
  3. Developers
  4. /
  5. SDK

SDK

The official TypeScript SDK (@fabhub/sdk) is generated and tested against the public OpenAPI contract, so its methods never drift from the public routes.

Install

npm install @fabhub/sdk

Requires Node.js 22+.


Authentication

Construct the client with an API key. An OAuth-issued access token is itself a pk_* key, so pass it as the same apiKey option.

import { FabHubClient } from '@fabhub/sdk';

export const fabhub = new FabHubClient({
  apiKey: process.env.FABHUB_API_KEY,
});

Methods

Client methodEndpointRequired scope
getCapabilitiesGET /v1authenticated
getAuthContextGET /v1/auth/contextauthenticated
listItemsGET /v1/itemsitems:read
createItemPOST /v1/itemsitems:write
getItemGET /v1/items/{item_id}items:read
listItemIngredientsGET /v1/items/{item_id}/ingredientsitems:read
listItemSuppliersGET /v1/items/{item_id}/suppliersitems:read
createItemIngredientPOST /v1/items/{item_id}/ingredientsitems:write
updateItemIngredientPATCH /v1/items/{item_id}/ingredients/{ingredient_id}items:write
createItemSupplierPOST /v1/items/{item_id}/suppliersitems:write
updateItemSupplierPATCH /v1/items/{item_id}/suppliers/{supplier_id}items:write
deleteItemIngredientDELETE /v1/items/{item_id}/ingredients/{ingredient_id}items:write
deleteItemSupplierDELETE /v1/items/{item_id}/suppliers/{supplier_id}items:write
getOrderGET /v1/orders/{order_id}orders:read
listOrderLinesGET /v1/orders/{order_id}/linesorders:read
createOrderPOST /v1/ordersorders:write
updateOrderPATCH /v1/orders/{order_id}orders:write
updateItemPATCH /v1/items/{item_id}items:write
deleteItemDELETE /v1/items/{item_id}items:write
listOrdersGET /v1/ordersorders:read
listContactsGET /v1/contactscontacts:read
getContactGET /v1/contacts/{contact_id}contacts:read
createContactPOST /v1/contactscontacts:write
updateContactPATCH /v1/contacts/{contact_id}contacts:write
deleteContactDELETE /v1/contacts/{contact_id}contacts:write
getOrganizationGET /v1/organizationorganization:read
getUsageSummaryGET /v1/usageusage:read
listStockLevelsGET /v1/stock-levelsinventory:read
listStockDocumentsGET /v1/stock-documentsinventory:read
getStockDocumentGET /v1/stock-documents/{document_id}inventory:read
createStockDocumentPOST /v1/stock-documentsinventory:write
listStockDocumentLinesGET /v1/stock-documents/{document_id}/linesinventory:read
createStockDocumentLinePOST /v1/stock-documents/{document_id}/linesinventory:write
updateStockDocumentLinePATCH /v1/stock-documents/{document_id}/lines/{line_id}inventory:write
submitStockDocumentPOST /v1/stock-documents/{document_id}/submitinventory:write
cancelStockDocumentPOST /v1/stock-documents/{document_id}/cancelinventory:write
approveStockDocumentPOST /v1/stock-documents/{document_id}/approveinventory:write
deleteStockDocumentDELETE /v1/stock-documents/{document_id}inventory:write
deleteStockDocumentLineDELETE /v1/stock-documents/{document_id}/lines/{line_id}inventory:write
updateStockDocumentPATCH /v1/stock-documents/{document_id}inventory:write
listWebhooksGET /v1/webhookswebhooks:read
createWebhookPOST /v1/webhookswebhooks:write
getWebhookGET /v1/webhooks/{webhook_id}webhooks:read
updateWebhookPATCH /v1/webhooks/{webhook_id}webhooks:write
deleteWebhookDELETE /v1/webhooks/{webhook_id}webhooks:delete
listWebhookDeliveriesGET /v1/webhooks/{webhook_id}/deliverieswebhooks:deliveries:read
listAuditEventsGET /v1/audit/eventsaudit:read

Pagination

let page = 1;
let totalPages = 1;
do {
  const result = await fabhub.listItems({ page, pageSize: 100 });
  // handle result.data
  totalPages = result.pagination.totalPages;
  page += 1;
} while (page <= totalPages);

Idempotent writes

const { data: item } = await fabhub.createItem(
  { name: 'Widget', itemType: 'product' },
  { idempotencyKey: crypto.randomUUID() },
);

Typed errors

import { FabHubApiError } from '@fabhub/sdk';

try {
  await fabhub.getItem('does-not-exist');
} catch (err) {
  if (err instanceof FabHubApiError) {
    console.error(err.status, err.code, err.message); // e.g. 404 NOT_FOUND ...
  }
}

Webhook signature verification

import { verifyFabHubWebhookSignature } from '@fabhub/sdk';

const result = verifyFabHubWebhookSignature({
  signingSecret: process.env.FABHUB_WEBHOOK_SECRET,
  rawBody, // the exact raw request body string/bytes, before JSON parsing
  timestamp: req.headers['x-fabhub-timestamp'],
  signature: req.headers['x-fabhub-signature'],
});

if (!result.ok) {
  // reject: result.reason explains why (e.g. 'invalid_signature')
}

Drift protection

The SDK operation mapping is checked against OpenAPI in CI, so public SDK methods cannot silently drift from public routes or point at internal surfaces.

HomeFeaturesPricingAboutArticlesDocumentationDevelopers
© FabHubPrivacy & CookiesTermsAccessibility