Provider workflows

Staging release: The workflows on this page were reviewed for the 60-entry staging catalog on September 7, 2026 and verified in staging. Public catalog snapshots observed October 28, 2026 list 60 entries in both staging and production (59 marked available/selectable and one FCI preview). Catalog status does not verify production requests or establish strict API parity. Check each provider in the first-request directory and query your environment's catalog before connecting.

Start with Connect your software for API keys, base URLs, SDK configuration, and response handling. The directory provides the request templates tested in staging and the public catalog report for each environment, including a downloadable JSON file. The production catalog report does not mean these request templates were tested in production. Relay Financial is unavailable until a direct API contract is implemented. These are synthetic workflows with documented limits.

The public catalogs report 60 entries each: 59 marked available/selectable and one FCI execute preview. These are catalog annotations, not a claim that all provider routes work in both environments. FCI is not selectable in the standard connector picker; confirm capability availability for your company before using it.

Use an organization runtime API key for companies in your workspace, or a company runtime API key for one company. Send it as X-API-Key. Native reads need read; native writes need write; execute reads need execute and read, while execute writes need execute and write. These keys authenticate to Fictix. The Chase access_token argument is optional and is not needed for synthetic banking operations.

Discover the current runtime catalog at /api/v1/catalog/connector-capabilities and export packs at /api/v1/catalog/export-packs. A connector's availability does not mean that every endpoint of the upstream vendor is implemented.

Native routes

Append the provider path to:

/api/v1/orgs/{company_slug}/native/{provider}
Providers Workflow covered by generated-company verification
Airtable List bases; create and retrieve a task record
Asana List tasks; create and retrieve a task
BILL List vendors; create and retrieve a vendor
Chargebee Read customers, invoices and transactions; manage customers, items, prices and subscription state
ClickUp Discover workspaces and lists; create, update, comment on and delete tasks
DocuSign Create, send and void envelopes; update recipients and download documents
Dropbox, OneDrive Read generated finance files; upload/download exact bytes and manage files/folders
Brex Cash accounts and transactions; manage virtual cards and vendor ACH accounts; post and retrieve transfers
Chase Read accounts and balances; manage recipients; post ACH, domestic wires and internal transfers
Mercury Manage payment recipients; post ACH, domestic wires and internal transfers; read ledger entries and update notes
Wise Business Discover a business profile and USD balance; create recipients and quotes; create, retrieve and cancel unfunded transfers
Monday Query boards and users; manage items, column values, groups and comments with GraphQL
Excel List worksheets; write and retrieve cell values
Rippling Read workers and users; create and update departments; create, update and delete teams
BambooHR Discover employees and field metadata; create and update personnel; filter and page through the roster
Expensify Discover and create policies; create draft expenses and reports; export and download report contents
Gmail Read, send and modify messages; manage drafts, labels and threads; retrieve raw MIME, attachments and history
Google Drive List files; create and retrieve a file
Google Ads Discover a test account; create, query, update and remove shared budgets and Search campaigns through v25 REST
Google Analytics 4 Validate and collect test web events; query their counts, users and page views with the Data API
Meta Ads Discover an ad account; create, retrieve, update, archive and delete campaigns with daily budgets
Gusto List employees; create and retrieve an employee
HubSpot List contacts; create and retrieve a contact
NetSuite List customers; create and retrieve a customer
Outlook List events; create and retrieve an event
Pipedrive Read and manage persons, organizations, deals, activities and products
Plaid Read transactions; refresh and retrieve the resulting event
QuickBooks, Shopify, Square, Stripe List customers; create and retrieve a customer
Slack Read the generated member directory through api/users.list
Ramp Read transactions; create and retrieve a card
Salesforce Query and manage CRM sObjects; compose requests with references and rollback
Sage Intacct XML queries and pagination; create, update and delete customers, vendors and GL accounts
Xero List contacts; create and retrieve a contact
Zendesk Manage users, organizations and tickets; append and retrieve ticket comments

Native writes require a nonempty idempotency key. Send a fresh Idempotency-Key header for each operation unless its workflow documents another header or body field. Reuse the key only when retrying the same operation and payload.

Rippling

Use /api/v1/orgs/{slug}/native/rippling as the REST base URL and send Rippling-Api-Version: 2024-08-01 (also the default). GET /workers/ and GET /users/ read generated personnel; GET /workers/{id}/ and GET /users/{id}/ retrieve one record. Worker and user IDs remain stable and are distinct. Supported worker fields include status, work email, title, start/end dates and references to users, managers and departments.

GET /departments/ derives the initial departments from canonical employee labels. Create with POST /departments/ and update with PATCH /departments/{id}/; both require name. An optional parent_id must reference an existing department, and reference_code persists. Renaming a department updates matching canonical employee department labels while keeping its Rippling ID. GET /teams/, POST /teams/, GET /teams/{id}/, PATCH /teams/{id}/ and DELETE /teams/{id}/ provide persistent team management. Team creation requires a name; updates change only submitted name/parent fields. Group names are unique within each resource. Parents must exist, cycles are rejected, and a team with children cannot be deleted. Writes require an Idempotency-Key and leave payroll and cash records unchanged.

Lists accept limit (1–100; default 50), cursor, and order_by using id, created_at or updated_at, comma-separated with optional asc/desc. Follow the returned next_link; the terminal page omits it. Cursors are scoped to the company, resource and query. Workers additionally accept one filter comparison on status, work_email, user_id, created_at or updated_at. String fields use quoted eq/ne; timestamps also support gt, ge, lt and le. For example, filter=status eq 'ACTIVE' returns active workers. Compound predicates and unsupported fields return explicit errors.

Expand supported relations using expand=user,department on workers, expand=parent on departments/teams, or two levels such as expand=manager.user,department.parent. The supported worker relations are user, manager, department and teams; generated team membership is empty. Hiring/termination writes, team-assignment writes, payroll, benefits, compensation, custom objects, permission administration and other API versions are outside this workflow. Missing optional fields are omitted.

Response and request fixtures come from Rippling's published OpenAPI. The official @rippling/rippling-sdk client can use this base URL and a Fictix X-API-Key header; supply Idempotency-Key on each write.

BambooHR

Use JSON requests under /api/v1/orgs/{slug}/native/bamboohr/api/v1 with a Fictix runtime key. GET /employees lists the generated company roster; GET /employees/directory returns the published directory and its fieldset. GET /meta/fields identifies supported aliases and their synthetic numeric IDs. GET /employees/{id} returns only id unless fields=firstName,workEmail,... is supplied. Numeric field IDs from the metadata also work. Employee internal IDs are immutable and distinct from editable employeeNumber values. An integration key is not bound to an employee, so GET /employees/0 returns {"id":"0"}.

Create employees with POST /employees and at least firstName and lastName. The response is 201 with the new employee and a Location header. Update only submitted fields with POST /employees/{id}. Writable fields are first/last/ preferred name, work/home email and phone, mobile phone, employee number, department, division, location, job title, hire date and Active/Inactive status. Work email and employee number must be unique within the BambooHR roster. Writes require an Idempotency-Key. Personnel changes remain visible through canonical company records; they do not create payroll or cash transactions. DELETE /employees/{id} hides that BambooHR resource and returns 204, preserving shared personnel and financial history used by other integrations.

The roster accepts page[limit] (1–2500), page[after] or page[before] using returned cursors and links. Filters use the comma-separated filter[ids] form, filter[status]=active|inactive, or case-insensitive substring matching for first/last name, job title name, work email, department/division/location name and employee number. Multiple filters combine with AND. Sort on employeeId, firstName, lastName, preferredName, jobTitleName or status, comma-separated with - for descending order. Cursors are bound to the company and query; changing or deleting the boundary employee invalidates that cursor. Additional roster fields use fields=workEmail,departmentName,... and have different aliases from single-employee reads. Use the documented comma-separated query forms.

Unknown requested read fields are omitted. Unsupported write fields and query forms are rejected. Directory sharing is fixed for the synthetic company; onlyCurrent=false includes future hires, while inactive employees stay hidden. An empty directory returns 404. Request Accept: application/json; XML, custom fields, photos, payroll, benefits, effective-dated job/compensation history and permission administration are outside this workflow. Endpoint fixtures are extracted from BambooHR's published OpenAPI.

Expensify

Send every job as POST to /api/v1/orgs/{slug}/native/expensify/Integration-Server/ExpensifyIntegrations. Use Content-Type: application/x-www-form-urlencoded and a requestJobDescription form field containing the job JSON. Plain JSON request bodies are unsupported. For example, a policy discovery job is:

{"type":"get","inputSettings":{"type":"policyList"}}

Authenticate with a Fictix runtime key in X-API-Key. A vendor credentials object may contain synthetic partnerUserID and partnerUserSecret strings for client compatibility; it is discarded before execution and persistence. Fictix does not authenticate against an Expensify account. Read scopes authorize get and download jobs. create and file jobs require write and a fresh Idempotency-Key. Retrying the same job with that key returns its saved result.

Policy discovery returns one company policy plus any policies you create. Use type: "create" with inputSettings.type: "policy", policyName and optional plan: "team" or "corporate" to create another. The result contains responseCode: 200, policyID and policyName.

For policy details, use a get job with inputSettings.type: "policy", a policyIDList array and a fields array. Supported fields are employees, categories, reportFields, tags and tax. Membership comes from the generated company's employees; the first employee is the synthetic policy owner. policyList also accepts userEmail and adminOnly. User emails must belong to that company. Categories, tags and tax start empty; the title is the only report field. Policy membership and configuration updates are unsupported.

A report creation job uses inputSettings.type: "report", policyID, a generated employeeEmail, report: {"title": "Travel"} and an expenses array. Each expense contains date in YYYY-MM-DD, merchant, currency: "USD" and positive integer amount in cents. The report stays Open / Draft.

A standalone expense creation job uses inputSettings.type: "expenses", employeeEmail and transactionList. These rows use created for their date and may also include reportID, policyID, externalID, category, tag, billable, reimbursable and comment. A report must belong to that employee; any supplied policy must agree with the report. The result includes string transactionID values and integer-cent amounts. externalID is an export label; use Idempotency-Key for retries. Each report or expense batch is atomic and contains at most 100 expenses. These writes do not reimburse employees, debit cash, allocate payments or post journal entries.

To export reports, send a file job with onReceive: {"immediateResponse": ["returnRandomFileName"]}, inputSettings.type: "combinedReportData", inputSettings.filters.reportIDList as comma-separated report IDs, and outputSettings.fileExtension: "csv" or "txt". Pass a separate template form field using the documented FreeMarker subset, for example:

Report,Merchant,Amount
<#list reports as report>
<#list report.transactionList as expense>
${report.reportID},${expense.merchant},${expense.amount}
</#list>
</#list>

Supported constructs are report and expense loops, addHeader conditions, scalar field interpolation, whitespace trim directives, division by 100, ?string("0.00"), boolean ?c / ?string, and string ?replace. Use the template's quoting and replacement syntax when fields may contain CSV commas, quotes or newlines. Other expressions and directives fail explicitly. Templates are limited to 8 KiB, exports to 100 reports and output to 1 MiB.

The export response is a plain filename. Send a download job with that fileName and optional fileSystem: "integrationServer" to retrieve the exact saved UTF-8 CSV or text bytes. Downloads remain unchanged when reports later receive new expenses. Filenames identify company-local stored exports.

Business failures return responseCode and responseMessage in a JSON body, so clients must inspect responseCode even when HTTP is 200. Malformed transport bodies and Fictix authentication failures use HTTP errors. FX, tax, approvals, custom report fields, arbitrary FreeMarker, reconciliation, reimbursements, SFTP, email actions and webhooks are unsupported. The contract follows Expensify's job reference and report template reference.

Wise Business

Use /api/v1/orgs/{slug}/native/wise_business/2026Q3 with a Fictix runtime key in X-API-Key. This contract follows Wise's published 2026Q3 API. Legacy v1, v2 and v3 paths and response formats are outside this contract.

GET /profiles returns the company-local business profile. Use its integer id for GET /profiles/{id} and GET /profiles/{id}/balances?types=STANDARD. The single standard USD balance reflects the company's first canonical USD bank account ordered by source ID. It is not an aggregate of all bank accounts. types=SAVINGS returns an empty list; balance creation and jars are unsupported.

Create a USD recipient with POST /accounts:

{
  "profile": 10001,
  "currency": "USD",
  "type": "aba",
  "accountHolderName": "Example Supplier",
  "ownedByCustomer": false,
  "details": {
    "legalType": "BUSINESS",
    "abartn": "064000020",
    "accountNumber": "40000000000",
    "accountType": "CHECKING",
    "address": {
      "country": "US",
      "firstLine": "1 Example Way",
      "city": "New York",
      "state": "NY",
      "postCode": "10025"
    }
  }
}

The recipient's id is an integer, and its name is returned in name.fullName. GET /accounts returns a content array and seek positions; use seekPositionForNext on the next request and stop when content is empty. Pages contain at most 20 recipients. Filters include profile, currency, active state and ownership, with id or currency ordering. DELETE /accounts/{id} deactivates the recipient; direct GET still returns it with active: false. Account details are validated structurally without a real bank lookup.

Create a quote at POST /profiles/{id}/quotes with sourceCurrency: "USD", targetCurrency: "USD" and exactly one positive sourceAmount or targetAmount. Amounts have at most two decimal places. Quotes use a synthetic rate of one, zero fees and a 30-minute lifetime. They do not represent live Wise pricing. Supply targetAccount when creating the quote or attach it with PATCH /profiles/{id}/quotes/{quoteId}. An expired or used quote cannot change.

POST /transfers accepts targetAccount, quoteUuid, a UUID customerTransactionId and optional details.reference. The result remains incoming_payment_waiting. The quote changes from PENDING to ACCEPTED and can create only one transfer, including during concurrent requests. Reusing customerTransactionId for the same normalized request retrieves that transfer; changing the request returns a conflict. HTTP retries also require the original Idempotency-Key.

Read transfers with GET /transfers/{id} or list them using profile, status, currency, creation-date, limit and offset filters. Cancel an unfunded transfer with PUT /transfers/{id}/cancel and an empty object. Its state becomes cancelled. These instructions never debit a bank account, reserve cash, create a payment allocation or post a journal entry. Funding, settlement, FX, other currencies, KYC, dynamic requirements, batches and webhooks are unsupported.

The response fixture is extracted from the published Wise OpenAPI. USD recipient field names follow Wise's published account example.

Salesforce, Pipedrive, Chargebee and Zendesk

These providers expose native routes as well as export packs. Point an HTTP client or an SDK with a configurable endpoint at its Fictix native base URL. Keep the runtime key in a server environment. Browser clients use an origin-bound browser token, as described in the native browser access guide.

Provider ID Example path after the native base Mutation format
salesforce /services/data/v66.0/query?q=SELECT%20Id,Name%20FROM%20Account JSON; create with POST, update with PATCH, delete with DELETE
pipedrive /api/v2/persons JSON; create with POST, update with PATCH, delete with DELETE
chargebee /api/v2/customers JSON or application/x-www-form-urlencoded; writes use POST
zendesk /api/v2/tickets JSON wrapped in ticket, user or organization; create with POST, update with PUT

Chargebee also accepts chargebee-idempotency-key, the official SDK's header. If both idempotency headers are present they must agree. A replay returns chargebee-idempotency-replayed: true. Its Product Catalog 2 subscription workflow is: create a customer, item family, plan item and item price; POST /api/v2/customers/{id}/subscription_for_items with subscription_items; then retrieve, update, cancel or reactivate that subscription. Invoice collection, proration, refunds and scheduled billing are outside this contract.

Salesforce supports scalar SOQL selection and comparisons, one-field ordering, COUNT(), LIMIT, and OFFSET. Composite requests support references such as @{account.id} and allOrNone rollback. Joins, general aggregates, tooling, Apex, provisioning and bulk APIs are outside this contract.

Pipedrive supports core collection operations and name search with cursor pagination. Saved filters, merges and changelogs are outside this contract. Zendesk comments are appended through ticket creation or update; closed tickets reject edits. Email delivery, attachments, bulk jobs and automations are outside this contract.

These are approximate synthetic APIs. Shared customer fields update the same canonical company records. CRM organization/contact views can originate from one canonical customer, and deleting a provider record hides that provider's record while preserving the shared entity. Spreadsheet export IDs retain their existing import contract and can differ from native API IDs.

Configure accounting before an external bank payout

Brex transfers to external vendors, Chase ACH/wire payments, and Mercury recipient payments need a company posting account. This is a prerequisite for the staging accounting workflow below; production payout accounting has not been qualified by these staging checks.

An organization owner or administrator selects the account in Settings → Company → Bank payout posting account and chooses Save account. Reload the page and confirm the same account is displayed before sending a payment. If that control is absent in your environment, customer setup is unavailable there; do not work around it by copying a Console session token or using an operator credential.

Choose an active canonical general-ledger account in the payout bank account's currency. Bank accounts, accounts receivable, accounts payable, and accounts linked to a bank are excluded. Saving the choice does not validate a future payment's currency; that check happens when the payment is posted. The setting is shared by these three providers within one company, so change it explicitly when the intended posting account changes. Clear saved account removes the choice and prevents subsequent external payouts until an account is saved again. These controls do not change the selected services, plan, or key scopes.

A native caller still needs an entitled plan and a key with write scope, plus the route's idempotency key. A missing posting-account choice returns HTTP 400 with a message asking you to configure the counteraccount. The native error envelope depends on the provider: Brex includes code CONFIGURATION_REQUIRED, Chase reports invalid_parameter with context, and Mercury includes the message in errors.general. Fix the company setting before retrying; do not treat that response as a completed payment. Internal transfers between company bank accounts are a separate workflow.

After a successful external payment, retrieve the provider operation and bank balance, then check canonical bank_transactions, journal_entries, and gl_entries or the exported books. The posting debits the chosen account and credits the bank's cash account. Readback must show one payment and one balanced posting, including after the provider's documented retry/replay behavior.

Brex cash and cards

Read cash accounts at /v2/accounts/cash and transactions at /v2/transactions/cash/{account_id}. Create virtual cards through /v2/cards with an owner from /v2/users. Card limits and lock, unlock and terminate operations are persistent and shared with execute.

Create a vendor at /v1/vendors with ACH payment_accounts; use its returned payment_instrument_id in /v1/transfers. Transfers are processed immediately in the synthetic ledger and debit the selected account once. Amounts in the native API use integer cents; execute amounts use dollars. Physical card delivery, PANs, approval policies, international wires and external bank settlement are outside this contract.

Mercury payments

Use /api/v1/accounts and /api/v1/recipients for account and recipient discovery. Create recipients with POST /api/v1/recipients, using name, emails and ACH electronicRoutingInfo or domesticWireRoutingInfo, including their US address. Recipient creation requires an Idempotency-Key header. Do not put idempotencyKey in the recipient JSON; that body field is supported for Mercury payment and transfer requests.

Send money with POST /api/v1/account/{account_id}/transactions; pass a positive dollar amount, recipientId, paymentMethod and a unique idempotencyKey. Repeating the body key returns HTTP 409 with the original transaction. If you also send an Idempotency-Key header, the two keys must agree.

POST /api/v1/transfer moves funds between project accounts and returns the paired debit and credit transactions. Synthetic payments settle immediately; the balance and ledger update in the same transaction. Native and execute calls share recipients and money movements. Check delivery, international payments, approvals and external bank settlement are outside this contract.

Gmail mailbox

Use /gmail/v1/users/me for the project's mailbox. POST /messages/send with {"raw":"<base64url RFC 2822 bytes>"} to store a sent message. Drafts use {"message":{"raw":"..."}}; sending a draft removes it and creates a sent message in the same thread. Native calls and execute email operations share messages, labels, drafts and history. No email leaves the synthetic mailbox.

Message and thread lists support maxResults, pageToken, repeated labelIds, and basic search terms such as from:, subject:, in:, has:attachment, after: and before:. Terms are combined with AND; prefix a term with - to exclude it. History requires startHistoryId and accepts historyTypes and labelId. Raw MIME attachments retain their bytes. Pub/Sub watches, mailbox settings, media upload sessions and advanced search are outside this contract.

Chase Embedded Payments

The native contract targets JPMorgan Embedded Payments: accounts and recipients use /embedded/v1/accounts and /embedded/v1/recipients; transactions use /embedded/v2/transactions. Discover the synthetic clientId and account IDs from the account list. Read balances at /accounts/{id}/balances.

Create a recipient with partyDetails, type: "RECIPIENT" and a US checking or savings account containing routingInformation. Supported rails are ACH and domestic WIRE. POST a transaction with a unique transactionReferenceId, debtorAccountId, recipientId, positive dollar amount, currency: "USD" and type. A TRANSFER instead uses creditorAccountId. A successful synthetic transaction is immediately COMPLETED and updates cash once. Retrying with the same HTTP idempotency key replays the response; reusing the reference in a new request returns 409. Account provisioning, RTP, international payments, verification and bank settlement are outside this contract. The response schema fixtures retain the published account/recipient 1.0.58 and transaction 2.0.58 contracts from JPMorgan's documentation.

Monday GraphQL

POST /v2 with query, optional variables and operationName. Queries need read; mutations need write and an Idempotency-Key. The selected GraphQL operation determines the required scope. Variables, aliases, fragments and directives are supported. Mutation fields commit together; any field failure rolls back all writes in that request.

Read boards, users, items and items_page; continue a page with next_items_page. Create items and groups, change column values, append/delete updates, archive/delete items, or move them between groups on their board. Generated boards expose status, due date, one assignee and priority text columns. Read columns.settings_str for status labels and numeric indices. Column writes accept JSON-encoded strings. Filters accept string or numeric CompareValue variables, with equality, text containment, empty checks and ordering. Queries are limited to 64 KiB, 12 selection levels and 1,000 expanded selections. Page size is at most 500. Board creation, custom columns, teams, subitems, subscriptions and webhooks are outside this contract. See the upstream item pagination contract.

Sage Intacct XML

POST XML to /ia/xml/xmlgw.phtml. Use the usual Intacct request, control, operation and function envelope with dtdversion 3.0. The Fictix runtime key authenticates the request. Vendor passwords and session values are discarded; do not provide real Intacct credentials. Reads need read; any write function needs write. Writes require an Idempotency-Key, or <uniqueid>true</uniqueid> with a stable control ID. A retry replays identical XML bytes.

Read CUSTOMER, VENDOR, GLACCOUNT, APBILL, ARINVOICE, GLBATCH, CHECKINGACCOUNT and SAVINGSACCOUNT through read, readByName, readByQuery, query and readMore. Create/update/delete is supported for customers, vendors and GL accounts. getAPISession returns a synthetic session. XML queries support explicit fields, scalar comparisons, boolean filters and ordering. Legacy readByQuery accepts one comparison; use query for compound filters. Return format is XML. Requests are limited to 1 MiB and 50 functions; responses to 4 MiB and 10,000 records. DTD and entity declarations are rejected. With transaction="true", any failed function aborts the entire operation. With false, successful functions persist independently. Inspect each XML result's status, including on HTTP 200.

The execute API additionally creates/posts bills, creates invoices, allocates payments, makes deposits/transfers and creates/posts balanced journals. These operations use the same canonical documents and cash accounts as native reads. Payment allocations reject overpayment; cash movements reject insufficient funds; journal posting updates GL balances once. Bill/invoice posting does not automatically produce GL journal entries. Historical balance snapshots, tax calculation, multi-currency accounting and external settlement are outside this contract. The optional official JavaScript SDK test covers the XML customer lifecycle; SDKs that enforce an Intacct hostname need a custom HTTP transport. See the upstream XML gateway reference.

Execute aging uses current outstanding balances and due-date buckets. The trial balance uses current GL balances. The cash-flow response reports bank ledger inflows/outflows for the requested dates; it does not classify investing and financing activity or claim a full accounting cash-flow statement.

Tasks, envelopes and files

ClickUp starts at /api/v2/team, followed by /team/{id}/space and /space/{id}/list. Create tasks with POST /api/v2/list/{id}/task; update with PUT /api/v2/task/{id}. Dates use Unix milliseconds. Updates to assignees use {"assignees":{"add":[123],"rem":[]}}; creation takes an array of IDs. Status, assignee and tag filters accept repeated statuses[], assignees[] and tags[] parameters. List pages contain at most 100 tasks.

DocuSign account discovery is GET /oauth/userinfo. Use the returned account ID under /restapi/v2.1/accounts/{accountId} for envelopes and templates. POST /envelopes accepts documents, recipients and emailSubject, or a templateId and templateRoles. PUT /envelopes/{id} supports sent and voided transitions. Documents download as bytes. Signing ceremonies and Connect webhooks are outside this contract.

Dropbox uses POST for its native file RPCs. /2/files/upload takes raw bytes and a Dropbox-API-Arg JSON header containing path and mode. /2/files/download takes the same header with a path or file ID, and returns bytes plus a Dropbox-API-Result metadata header. Metadata, download and folder-list RPCs need only the read scope. Both Dropbox API and content host paths use this one Fictix native base.

OneDrive uses Graph paths such as /v1.0/me/drive/root/children and /v1.0/me/drive/root:/example.txt:/content. PUT content takes raw bytes; GET content returns those exact bytes. Folder creation uses POST children with name and folder: {}. PATCH an item to rename or move it; DELETE removes it and its descendants. If-Match accepts the item's current eTag.

The file APIs preserve arbitrary bytes, including JSON and empty files. Uploads are limited to 1 MiB per request. Generated finance files are seeded independently for each storage provider. Upload sessions, sharing, delta synchronization and subscriptions are outside this contract.

Freshdesk support workflows

Use /native/freshdesk/api/v2 beneath the company route. Contact and company CRUD, agent discovery, ticket CRUD, ticket replies and private/public notes persist in the generated company. Creating a ticket with an email can create its requester. Read and edit conversations through their ticket, and resolve tickets using status 4 (5 closes them). Lists support page, per_page and a next-page Link; ticket lists default to the past 30 days. Use include=description,requester on lists and include=conversations on a ticket detail to inspect its first ten conversations.

Supply a Fictix runtime key and Idempotency-Key for writes. Reusing a key with the same request preserves the original result. Replies and notes remain synthetic. Attachments, configured custom fields, automation, structured chat bodies and analytics are outside this adapter's contract.

Front discussion and task workflows

Use /native/front beneath the company route. Contacts support CRUD and handle changes, with email/phone handles linked to canonical customer fields. Read inboxes and teammates, then create a discussion with its initial comment, or a task with a description and optional future due_at timestamp. Both require an inbox or a list of teammates. Comments, assignment, archival, trash and deletion persist. A conversation must be in the trash before permanent deletion; only a comment's creating Fictix credential may edit its body.

Collections use Front's _results response and _pagination.next links. Contact timestamp filters and conversation status filters use the JSON q parameter. Write calls require Idempotency-Key, including DELETE operations that carry a JSON body. Mail channel sending/import, attachments, contact lists, custom field definitions, ticketing status categories and automations are outside this contract.

Help Scout inbox workflows

Use /native/help_scout/v2 beneath the company route. Create a customer, read its Resource-ID response header, and retrieve it using the Location header. Creates have empty response bodies. The same headers survive idempotent replay. Customer PATCH requests take an array of operations; PUT overwrites profile fields, clearing omitted fields while retaining email and phone entries.

Read mailboxes and users, then create a conversation with a customer and at least one thread. Customer messages, replies, notes, chat and phone threads, assignment, status updates and draft publication persist. Conversation PATCH takes one operation object. Published replies reactivate a conversation unless they specify another status; imported customer threads preserve its status. Lists use HAL _embedded, _links and page objects; conversation lists default to active conversations. Use status=all to include closed ones.

Writes require Idempotency-Key. Customer deletion removes that provider's customer and associated conversations from its API. Advanced search, configured custom fields, teams, organizations, attachments, automated audit threads, merging, reports and webhooks are outside this contract. The inbox and user directory are synthetic, and no live messages are sent.

Intercom customer and conversation workflows

Use /native/intercom beneath the company route with Intercom-Version: 2.16. Contacts, company upserts and contact/company associations share canonical customer records. Create a conversation from a contact, then add replies or notes, assign an admin, close, reopen or snooze it. Creates return HTTP 200; conversation creation returns a message with its conversation_id.

POST contacts/search, POST conversations/search and POST companies/list are reads and accept read-only keys without an idempotency header. Search cursors bind to the company and query. Contact timestamp searches compare UTC calendar days; the stored timestamps retain seconds. Writes require Idempotency-Key. Custom attributes, teams, brands, attachments, quick replies, contact archive/merge, Messenger, automation, reports and webhooks are excluded.

For server-side code using intercom-client@7.0.3, its public configuration supports the native base URL and headers:

const client = new IntercomClient({
  token: "fictix",
  baseUrl: `${companyBaseUrl}/native/intercom`,
  headers: {
    Authorization: "",
    "X-API-Key": process.env.FICTIX_RUNTIME_KEY,
    "Intercom-Version": "2.16",
  },
});
const contact = await client.contacts.create(
  { role: "user", email: "customer@example.test", name: "Test customer" },
  { headers: { "Idempotency-Key": crypto.randomUUID() } },
);

The token placeholder satisfies the SDK constructor; the runtime key authenticates the request. The additional header selects 2.16 because this SDK release's typed version option ends at 2.14. All conversations remain synthetic.

Close CRM workflows

Use /native/close/api/v1 beneath the company route. Leads, contacts, opportunities, tasks and Note activities support creation, independent reads, updates with PUT, and deletion. A lead can include nested contacts when created; a contact or opportunity without a lead creates one atomically. Invalid nested records roll back the entire write. Lead deletion removes its Close children while retaining the underlying shared business records.

Opportunity values use integer minor units. Monthly values are multiplied by 12 for annualized totals; list aggregates cover all matching records before pagination. The synthetic workspace provides one Sales pipeline, Active/Won/Lost opportunity statuses, and Potential/Qualified/Bad Fit lead statuses. A transition to Won supplies date_won when missing and respects X-TZ-Offset. Reopening a won opportunity preserves its existing win date. Tasks support lead and outgoing-call records, assignment and completion; these records do not place calls.

Lists use _limit (1–100), _skip (0–10000), data and has_more. Contacts can be filtered by lead. Opportunities, tasks and notes support the documented simple relationship and date filters implemented in the connector; unsupported query parameters return a validation error. _fields accepts top-level field names. Status, pipeline and user discovery are read-only.

The official closeio==2.1 Python package can use its public API class with a custom base URL and the Fictix runtime header:

from closeio_api import API

client = API(company_native_base + "/api/v1/", api_key="fictix", tz_offset="0")
client.session.headers["X-API-Key"] = runtime_key
lead = client.post("lead", {"name": "Example"},
                   headers={"Idempotency-Key": operation_id})

This covers plaintext notes, core CRM records and task workflows. Rich-text HTML input, attachments, configured custom fields, advanced/text search, grouped reports, merge, moving contacts with linked records, automation, configuration writes and webhooks are outside this contract. Browser callers use origin-bound short-lived bearer tokens. No live Close requests or communications are sent.

GitHub issue workflows

Use /native/github beneath the company route. GET user/repos discovers the synthetic private repository fictix/demo-workspace. Issues share the company's task records and support creation, edits, assignment, labels, milestones, comments, closing and reopening. Label and milestone configuration supports creation, editing and deletion. Issue numbers remain stable across task edits.

The default REST API version is 2022-11-28. Set X-GitHub-Api-Version to 2026-03-10 for the newer contract; it accepts assignees and rejects the removed singular assignee write field. Responses identify the selected version. Lists support page/per-page parameters and scoped Link URLs. JSON GET responses support ETag and If-None-Match. Writes require Idempotency-Key.

The official Octokit client can use a custom base URL and public request hook:

const client = new Octokit({ baseUrl: `${companyBaseUrl}/native/github` });
client.hook.before("request", (options) => {
  options.headers["X-API-Key"] = process.env.FICTIX_RUNTIME_KEY;
  options.headers["X-GitHub-Api-Version"] = "2026-03-10";
});
const issue = await client.rest.issues.create({
  owner: "fictix", repo: "demo-workspace", title: "Example task",
  headers: { "Idempotency-Key": crypto.randomUUID() },
});

Repository and collaborator discovery are read-only. This contract covers issue tracking and Markdown bodies. Git transport, repository content, branches, commits, pull requests, reviews, Actions, GraphQL, rendered HTML, notifications and webhooks are excluded. Repository URLs describe synthetic metadata; these workflows do not create repositories or issues on github.com.

Linear issue and project workflows

Send GraphQL JSON bodies to /native/linear/graphql beneath the company route. Read teams, users and workflowStates to discover the synthetic Engineering team, generated employees and Backlog/Todo/In Progress/Done/Canceled states. Issue mutations share canonical tasks; project renames update the names on their tasks. Markdown comments, labels, assignment, parent issues and project membership persist and can be read through their related records.

Queries accept read-only runtime keys without Idempotency-Key. Mutations require write scope and an idempotency key. Reuse that key for a retry; choose a new key for each different mutation. All mutation fields in one request commit together or roll back together. Aliases, fragments, variables and named operation selection use GraphQL schema execution.

The official @linear/sdk@93.0.1 uses public endpoint and header options:

const client = new LinearClient({
  apiKey: "fictix",
  apiUrl: `${companyBaseUrl}/native/linear/graphql`,
  headers: { "X-API-Key": process.env.FICTIX_RUNTIME_KEY },
});
const teams = await client.teams();
client.client.setHeader("Idempotency-Key", crypto.randomUUID());
const created = await client.createIssue({
  title: "Example task", teamId: teams.nodes[0].id,
});
const issue = await created.issue;

Lists use Relay nodes, edges and pageInfo, with first/after or last/before. Page sizes are 1–100. Cursors bind to the company, generation, relationship and filters. Basic field comparisons, related-record filters and bounded and/or groups are supported. Use absolute timestamps and orderBy with createdAt or updatedAt; custom sort expressions and relative durations are excluded. Archived and trashed issues/projects are hidden from default lists; includeArchived: true includes them. Delete trashes these records and unarchive restores them. Explicit permanent issue deletion removes its Linear projection.

The schema is a supported subset of Linear's published contract. Team, user and status configuration, rich document state, cycles, roadmaps, initiatives, releases, external integrations, reactions, attachments, subscriptions, notifications, webhooks and automation are excluded. These workflows remain inside the generated company and do not send requests or notifications to Linear.

Execute routes

Chase, Monday, Sage Intacct, ClickUp, DocuSign, Dropbox and OneDrive expose both execute and native APIs backed by the same project records. FCI provides derived financial summaries through execute and retains preview status.

POST /api/v1/orgs/{company_slug}/execute
X-API-Key: YOUR_RUNTIME_KEY
Content-Type: application/json

{
  "org_id": "YOUR_COMPANY_PROJECT_ID",
  "user_id": "your-integration",
  "turn_id": "unique-operation-id",
  "capability_key": "sage_intacct.customers.list",
  "args": {}
}

The legacy org_id field identifies the generated company project, not the workspace organization. Check the response's status: execute errors may use HTTP 200 with status: "error". Reuse turn_id when retrying an operation.

Provider Workflow covered by generated-company verification
Chase Read accounts; create a synthetic ACH/wire payment; retrieve it and its changed balance
ClickUp Read generated teams/lists; create, update and retrieve tasks and comments
DocuSign Create a synthetic envelope; retrieve documents and recipients; send and void it; create from a template
Dropbox, OneDrive Create folders; upload, list and download the same binary content
FCI Read financial summaries derived from the generated company
Monday Create and update items; preserve board/group membership and comments
Sage Intacct Manage customers/vendors and GL accounts; create and post bills/journals; allocate payments and move cash

File content uses base64. File paths are scoped to the company and provider. Missing files, tasks, envelopes and payments return an error. Synthetic DocuSign state changes do not send an email, and synthetic Chase payments do not move money through a bank. Future-dated Chase execution is unsupported.

Export packs

Download a ZIP from /api/v1/orgs/{company_slug}/export-pack/{target}. The seven targets are qbo, hubspot, asana, chargebee, pipedrive, salesforce and zendesk. These contain generated company records in the documented spreadsheet layouts. Some captured pack members intentionally contain headers only; consult each pack's schema for supported artifacts.

Coverage and fidelity

The workflows here describe supported operations, request forms, and observable state changes. Additional vendor endpoints need their own compatibility verification. Inspect the capability metadata and test the exact methods your software uses. Native-shaped responses remain approximate; they are not a certification of full upstream API parity.

Paddle Billing

Use provider ID paddle with Paddle-Version: 1 (also the default). Manage customers, their addresses/businesses, products and prices through Paddle's usual POST, GET and PATCH paths. Archive catalog records with status: archived; list them explicitly with status=archived. Lists use per_page, after and meta.pagination.next, scoped to the company.

For a manual invoice, create a product and price, then POST /transactions with collection_mode: manual, items: [{price_id, quantity}] and billing_details.payment_terms: {interval: day, frequency: 30}. Add the customer_id and a matching address_id to make it ready, then PATCH its status to billed. Billing creates an invoice visible through the canonical accounting records. Recurring prices also create a subscription; retrieve its ID from the billed transaction. There is no POST /subscriptions endpoint.

Subscriptions support immediate pause/cancel with effective_from: immediately. Resume before the previous billing period ends with on_resume: continue_existing_billing_period. Scheduled changes, new renewal invoices and proration are excluded. Subscription customer/address/business, billing details and custom data can be updated. Billed transactions permit custom-data edits only; draft/ready transactions may be canceled.

Catalog prices support USD, EUR and GBP. Manual financial writes support USD, zero-tax fixtures without discounts, and positive totals up to 999999999999 cents. Billing does not collect money or post a general-ledger journal. Automatic payments, checkout, hosted portals, tax calculation, adjustments/refunds, trials, reports and webhooks are outside this contract. Portal URLs are synthetic metadata, not functioning hosted pages.

The official JavaScript @paddle/paddle-node-sdk@3.10.0 is tested without changing its serialization or response classes. Its environment option accepts the Fictix base URL at runtime and customHeaders carries the runtime key and idempotency key. The package's TypeScript Environment enum does not advertise arbitrary base URLs. No live Paddle calls, payments or notifications are sent.

Recurly

Use provider ID recurly and Accept: application/vnd.recurly.v2021-02-25. Create accounts with a unique code and fixed-price plans with code, name and currencies: [{currency: USD, unit_amount: 25}]. Account codes and plan codes can be fetched with /accounts/code-{code} and /plans/code-{code}. Accounts map to shared customers; plans map to shared inventory items. Plan updates use PUT and return 201, following the published API specification.

POST /subscriptions with plan_code, account: {code}, currency: USD, collection_method: manual and an optional quantity. This creates the account if needed, the subscription and one canonical invoice in the same transaction. Retrieve invoices through /subscriptions/{id}/invoices, /accounts/{id}/invoices, /invoices/{id} or /invoices/number-{number}. Subscription UUID lookup uses /subscriptions/uuid-{uuid}. Billing lists contain records created through this Recurly adapter. Manual net terms include the additional 24 hours used by Recurly: net_terms: 30 becomes due 31 days after invoice creation. Subscription metadata changes affect future settings; they do not rewrite an existing invoice.

PUT /subscriptions/{id}/cancel with timeframe: term_end or bill_date to mark the subscription canceled. Reactivate it before its expiry with PUT /subscriptions/{id}/reactivate. DELETE /subscriptions/{id}?refund=none terminates it immediately and leaves the invoice outstanding. Account deactivation requires all its Recurly subscriptions to be terminated; PUT /accounts/{id}/reactivate restores the account. Removed plans remain readable and cannot be used for new subscriptions.

Lists use limit (1–200), timestamp sort, order, begin_time, end_time and scoped cursor URLs in next. Account lists support email/subscriber filters; plans, subscriptions and invoices support their documented state filters. The ids filter returns at most 200 IDs and cannot be combined with pagination or other filters. Unsupported parameters return validation errors.

Plans support USD/EUR/GBP, fixed prices with at most two decimal places, day/month intervals, no setup fee and no trial. Financial writes support USD totals from 0.01 to 9,999,999,999.99 with zero tax. Renewal flags and term dates are stored; automatic renewals and scheduled expiry do not execute. Proration, pauses, payment collection/refunds, purchases, coupons, add-ons, tax calculation, general-ledger posting, webhooks and HEAD list counts are outside this contract.

The official recurly@4.79.0 Node SDK is tested with its serializers, resource classes, errors and pagination unchanged. It has no public base URL option, so the test routes its HTTPS transport to a loopback bridge. Public request headers carry X-API-Key and Idempotency-Key; applications using this SDK need a transport override or proxy for the Fictix endpoint. No live Recurly traffic or payment collection occurs.

PayPal

Use provider ID paypal. Create catalog products at /v1/catalogs/products with name and type (PHYSICAL, DIGITAL or SERVICE). Products map to shared inventory items. Their published PATCH operations support add, replace and remove for description, category, image URL and home URL. Product name and type are immutable through PATCH. Custom product IDs must be 6–50 URL-safe letters, digits or ._~-; omitted IDs receive the PROD- prefix. Product lists use page numbers, page_size up to 20 and optional total_required=true.

Search generated payment history through /v1/reporting/transactions with absolute start_date and end_date timestamps spanning at most 31 days. Page sizes can reach 500. Supported filters are exact transaction ID, T-code, status and currency. Select fields=transaction_info, payer_info or all. Captured-payment records come from positive canonical customer payments; retrieve a report's transaction ID at /v2/payments/captures/{id}.

POST /v2/payments/captures/{id}/refund with an empty object to request the remaining captured amount, or amount: {currency_code: USD, value: "0.50"} for a partial refund. Read it at /v2/payments/refunds/{id}. Requests remain PENDING and reserve that amount against further requests. Concurrent requests cannot reserve more than the capture. Pending refunds appear in transaction searches with balance_affecting_records_only=N, status P and event T1107. They do not change the original payment, invoice, cash or general ledger.

Writes accept PayPal-Request-Id (1–38 characters) or Fictix Idempotency-Key; both headers must agree when supplied together. Responses use full representation, including with Prefer: return=representation. Minimal representation, refund settlement, checkout/orders, authorizations, vault, billing plans/subscriptions, payouts, balance reports, disputes, mock-response headers, delegated merchant assertions and webhooks are outside this contract.

The official @paypal/paypal-server-sdk@2.5.0 test uses configured Axios headers to carry X-API-Key and its unstable_httpClientOptions adapter hook to route requests into the local bridge. A local OAuth token prevents vendor token fetches; Fictix authenticates the runtime key. Generated request and response schemas, headers and error handling remain unchanged. This SDK does not expose a general base URL option; applications need a transport override or proxy for Fictix. No PayPal traffic or real refund is sent.

Adyen Checkout workflows

Use /api/v1/orgs/{slug}/native/adyen/v72 with your Fictix runtime key in X-API-Key and merchantAccount: "FictixDemo". Each company has its own merchant data. Writes require idempotency-key of at most 64 characters; replays return the original response and conflicting bodies return error 704. POST /paymentMethods is a read operation and works with a read-only key.

Checkout v72 supports Visa and Mastercard method discovery, allow/block lists, shopper token creation/listing/deletion, manual authorization, and asynchronous capture, cancellation and refund requests. Tokens are scoped to their shopper reference, support the three published recurring processing models, and can also be stored during authorization. Repeated token creation for the same shopper, card and expiry returns the existing token. Deleting a token prevents reuse.

For test-card input, use paymentMethod.type: "scheme", encryptedCardNumber: "test_4111111111111111" for Visa or "test_5555555555554444" for Mastercard, encryptedExpiryMonth: "test_03", encryptedExpiryYear: "test_2030", and encryptedSecurityCode: "test_737". Valid future month/year combinations are accepted. These are Adyen's documented synthetic test credentials; the adapter does not decrypt cards.

Authorization requires a positive integer USD amount in cents, a reference of at most 80 characters, an absolute HTTP(S) return URL, and additionalData: {"manualCapture": "true"}. It returns Authorised and keeps the payment separate from settled customer payments. Captures and cancellations apply to these open native authorizations. Refunds apply to existing posted or settled canonical customer payments. Modification responses return received; amounts are reserved so competing requests cannot over-capture or over-refund. A pending capture is not eligible for a refund. Pending cancellation prevents further capture. Cash balances, invoice balances and journal entries remain unchanged until settlement, which this workflow does not implement.

The official @adyen/api-library 32.1.0 SDK is exercised against these routes, including its generated serializers, authentication, token methods, payment methods, modification responses and parsed errors. The SDK has no public Checkout base-URL setting; route its HTTP transport to the company native prefix while retaining the /v72/... path. The checked-in SDK test redirects only the socket destination to a local HTTP bridge and prohibits upstream traffic.

Automatic/delayed capture, authorization expiry, refund settlement, declines, 3DS, sessions, hosted checkout and payment links, other payment methods, splits, balance-platform operations and webhooks are outside this contract.

QuickBooks query and amount behavior

The QBO query route supports SELECT * FROM <Entity>, optional single equality filters, STARTPOSITION, and MAXRESULTS (1–1000). All entities support Id; invoices support DocNumber/CustomerRef, bills and bill payments VendorRef, payments CustomerRef, customers and vendors DisplayName, accounts and items Name, and journal entries DocNumber. Filters use exact string values and backslash escaping for apostrophes. Filtering happens before pagination. Unsupported operators, compound predicates, sorting, and extra statements return a QBO fault. Invoice and bill totals use the shared accounting total; money fields are JSON numbers, including zero balances.

FreshBooks accounting workflows

Use /api/v1/orgs/{slug}/native/freshbooks with X-API-Key, Api-Version: alpha (the default), and Idempotency-Key on writes. Identity discovery at GET /auth/api/v1/users/me returns the company-local FICTIX account. Accounting routes start with /accounting/account/FICTIX: /users/clients, /items/items, /invoices/invoices, and /payments/payments. Clients, items and invoices support POST, list/single GET, and PUT by ID. Payment allocations support list/single GET. Bodies use the singular resource wrapper, such as {"client":{"fname":"Ada","lname":"Lovelace"}}.

Create an invoice with an active customerid, create_date in YYYY-MM-DD format, and ordinary lines containing name, decimal qty, and unit_cost: {"amount":"12.50","code":"USD"}. Up to 100 lines are accepted; each line is rounded to cents before totals are summed. Omitted invoice numbers are allocated uniquely within the company. due_offset_days supports 0–3650. PUT replaces the complete line array when supplied; omitted fields are retained.

Invoices start as drafts outside the shared invoice collection. PUT {"invoice":{"action_mark_as_sent":true}} issues the invoice with the same native ID and exposes it to other integrations. This action sends no email. Only invoices created through this adapter can be updated; paid and partially paid invoices cannot be changed. Invoice and item price writes support USD. Client currency preferences also support EUR and GBP. Payment reads expose one row per existing invoice allocation, preserving its amount and invoice/customer links; unapplied balances are omitted.

Lists support page, per_page, documented scalar search fields, and supported sort fields. Page zero becomes page one; page size defaults to 15 and is capped at 100. PUT vis_state: 1 deletes a resource from normal reads, 2 archives it, and 0 restores it. The delete response contains the updated resource, matching the official SDK fixtures. Unsupported parameters return an error.

The official @freshbooks/api 4.1.0 SDK is exercised through its public apiUrl setting and an Axios transport adapter that adds the Fictix runtime key and idempotency headers. Applications using this SDK need those transport headers; its OAuth bearer token alone does not authenticate with Fictix. SDK request and response conversion, money/date parsing, pagination and errors are preserved.

Tax and discount calculation, automatic billing, payment collection, journal posting, invoice email, credits, expenses, projects, time tracking, reports, attachments, secondary contacts and webhooks are outside this workflow.

Zoho Books accounting workflows

Use /api/v1/orgs/{slug}/native/zoho_books/books/v3 with your Fictix runtime key in X-API-Key and Idempotency-Key on writes. GET /organizations returns the company-local organization ID 100000000000001 and USD currency ID 100000000000002. Every subsequent request requires ?organization_id=100000000000001; another organization ID is rejected.

/contacts supports customers and vendors, addresses and up to ten contact people with one primary contact. POST requires contact_name; PUT by contact ID requires contact_name and contact_type. The contact type cannot change. /items supports sales items with a name and numeric USD rate. POST and PUT require name and rate; a zero rate is valid. Contacts and items support GET by ID, list GET, and POST /{id}/active or /{id}/inactive.

POST /invoices creates a draft with an active customer_id and line_items that reference active item_id values. Lines accept positive decimal quantity and an optional numeric rate; amounts are rounded to cents per line. Invoice totals must be positive. PUT by invoice ID replaces the complete line array and requires the customer ID again. Omitted invoice numbers are allocated uniquely. Dates use YYYY-MM-DD; payment terms support up to 3650 days. Invoice and item price writes use USD, without tax, discounts, shipping, adjustments or FX.

POST /invoices/{id}/status/sent issues the draft into the shared invoice collection with the same native ID. The action sends no email. Issued invoices are immutable through this adapter. DELETE supports only drafts created through this adapter. Native-created contacts and items can be deleted when no financial transaction references them. A deleted draft releases those references.

/customerpayments supports list and single reads of settled payments and their invoice allocations. Pending payments are omitted. Lists support documented scalar filters, supported status filters, sort_column, and stable ascending order. page starts at one; per_page defaults to 10 and accepts 1–200. Unsupported parameters return an error. JSON response contracts are checked against the published OpenAPI modules; invoice totals and balances follow the numeric wire examples where the schema's string annotation disagrees.

Payment collection, journal posting, invoice email, recurring invoices, estimates, sales orders, purchasing, inventory movements, credit notes, vendor payments, reports, attachments, custom fields, portals, regional tax settings and webhooks are outside this contract. The workflow makes no live Zoho requests.

Klaviyo profiles, lists and events

Use /api/v1/orgs/{slug}/native/klaviyo as the SDK base URL, with a Fictix API key and revision: 2026-07-15. Writes require Idempotency-Key. JSON responses use application/vnd.api+json. These workflows are checked against Klaviyo's published OpenAPI category specifications and the official klaviyo-api Node SDK 23.0.0.

  • Profiles: list/read, create, update and synchronous POST /api/profile-import upsert. Email, phone and external ID resolve existing profiles; conflicting identifiers return 409. Names, email and phone remain linked to canonical customers. Custom properties and location fields merge; null clears submitted fields. At least one identifier must remain.
  • Lists: create/read/update/delete, read member profiles or their relationship IDs, and add/remove up to 1,000 profiles atomically. Repeated additions preserve the original join time. Deleting a list preserves its profiles. additional-fields[list]=profile_count reports current membership. Membership changes do not grant marketing consent.
  • Events: POST /api/events persists a submitted event and its profile/metric relationships, then returns an empty 202. Accepted synthetic events are immediately available through event list/read endpoints. The first event with a given profile, metric and unique_id is retained; when omitted, the event time to the second is the deduplication key. Optional value is represented as $value in event properties; it has no financial effect.
  • Metrics: list/read API metrics created by submitted events. No engagement, purchase or campaign metrics are fabricated from unrelated financial records.

Profile and list reads support their published basic identifier/date filters. Event reads support profile ID, metric ID, datetime and timestamp comparisons. List-member reads support email, phone and join-date filters; metrics support integration name/category equality. Supported predicates compose with and, or, not or comma-separated conjunctions, bounded to 16 expressions and four nested levels. String literals use quotes; any accepts a string array. Unsupported fields/operators fail explicitly.

Sorting is limited to the published fields implemented for each endpoint. Pagination honors profile/member limits of 1–100, list limits of 1–10, event limits of 1–1,000 and a fixed 200-metric page. Cursors bind to the company, incarnation, endpoint, query and ordered record IDs; insertions, removals or reordering require starting again. Next/previous links use the same Fictix native base URL. Unavailable links are omitted. Sparse fieldsets support implemented attributes and nested location fields. Event reads can include profile,metric; individual profile reads can include lists.

Campaign delivery, email/SMS subscriptions, consent administration, SMS provisioning, attribution, predictive analytics, segments, flows, bulk jobs, profile merge/deletion, profile meta patches and value_currency are outside this workflow. Unsupported versions, requests and query parameters return errors. E.164 phone syntax is validated; upstream account-specific SMS rules are not simulated. No messages are delivered and no money or ledger entries change.

Mailchimp audiences, members and tags

Use /api/v1/orgs/{slug}/native/mailchimp/3.0 as the Marketing SDK base URL, with a Fictix API key. Writes require Idempotency-Key. These workflows are checked against Mailchimp's published Marketing API specification 3.0.91 and the official @mailchimp/mailchimp_marketing Node SDK 3.0.80.

  • Audiences: list/read, create, update and delete through /lists. Creation requires the published audience settings, contact and campaign defaults. Updates require the complete settings payload, including contact state and postal code. Deletion preserves canonical customers.
  • Members: list/read, create, update, PUT upsert and archive through /lists/{list_id}/members. The subscriber hash is MD5 of the lowercase email address. Email changes update that identifier. Names, email and phone remain linked to canonical customers. An archived member is excluded from ordinary reads; status=archived lists archived records, and upsert can restore them.
  • Tags: list a member's tags, add/remove named tags atomically, and search audience tags. Repeated additions preserve the original assignment time.
  • Merge fields: read the fixed FNAME, LNAME and PHONE definitions. These values update the corresponding canonical customer fields.

The initial audience f1c71ca001 derives its contacts from canonical customers with email addresses. Those initial contacts have transactional status; no marketing consent is inferred. Its sender and postal address are explicitly synthetic placeholders. Custom audiences contain only explicitly added members. Archiving preserves the canonical customer, and deleting the initial audience does not silently recreate it. Audience counts reflect current member statuses; campaign counts are zero because campaign activity is not simulated.

Lists support email/date filters and creation-date sorting. Members support status, email type, unique email ID, VIP and timestamp filters, with sorting on the implemented opt-in, signup and change timestamps. Collection reads accept count from 1 to 1,000 and a nonnegative offset. fields and exclude_fields select response fields and cannot be combined. Unsupported query parameters and write fields fail explicitly. Errors use application/problem+json.

Campaign creation or delivery, engagement reporting, automations, commerce, custom merge-field administration, interests, marketing permissions, notes, SMS, bulk jobs and permanent contact deletion are outside this contract. Submitted subscription statuses and campaign defaults are synthetic state; they do not deliver messages or change a live Mailchimp account.

Deel personnel and organization structures

Use /api/v1/orgs/{slug}/native/deel/rest as the base URL, with a Fictix API key. Writes require Idempotency-Key. These workflows use Deel's published OpenAPI specification 1.25.0 and its operations dated 2026-01-01.

GET /people and GET /people/{hris_profile_id} expose canonical personnel, stable UUIDs, names, work and personal emails, job titles, start dates, departments and manager/report relationships. Active and future start dates determine personnel status. Employment-contract arrays are empty because this workflow does not create Deel contracts. GET /organizations returns the current synthetic organization.

People lists support name search, supported name/identifier/date/job/status sorts, repeated hiring_types, hiring_statuses and person_statuses query parameters, and repeated fields parameters for implemented top-level fields. Pages use offset and limit, defaulting to 100 records with a maximum of 200. The page object reports the filtered total and requested page size. Unsupported selectors, filters and relationship expansions return errors.

/hris/organization_structures supports list/create/read/update/delete, with individual lookup, update and deletion also available through /hris/organization_structures/external/{external_id}. Structures hold named teams and optional external IDs. Creation uses is_multiple_select, its response uses is_multi_select, and later reads/updates use is_multiselect, following the published contracts. Updates require teams; existing team IDs preserve identity, and omitted teams are removed. Each structure supports up to 200 flat teams. PATCH and DELETE acknowledge success with an empty 200.

The initial Departments structure reflects canonical department assignments. Renaming a department team updates the corresponding personnel records. Removing an assigned department or its structure fails atomically. Custom structures do not implicitly assign staff or modify payroll.

Person creation, people without contracts, contract hiring/signing, invitations, payroll, benefits, payments, worker assignment, custom fields, roles, team hierarchies and webhooks are outside this workflow. No live Deel calls occur.

Meta Ads account and campaigns

Use /native/meta_ads/v26.0 with a Fictix runtime key. Discover the synthetic account with GET me/adaccounts, or read GET act_1000000001?fields=id,account_id,name,currency,timezone_name. The account uses USD and UTC. Campaigns start empty.

POST act_1000000001/campaigns with JSON or the official SDK's URL-encoded form:

{
  "name": "Website traffic test",
  "objective": "OUTCOME_TRAFFIC",
  "special_ad_categories": [],
  "daily_budget": 1000,
  "status": "PAUSED"
}

The response supplies id. Read GET {id}?fields=name,status,daily_budget to verify persisted values. The daily budget is in currency minor units: 1000 represents USD 10.00 and is returned as the string "1000". This workflow supports auction campaigns, OUTCOME_TRAFFIC or OUTCOME_AWARENESS, daily campaign budgets, LOWEST_COST_WITHOUT_CAP bidding, no special ad categories and no ad-set budget sharing. New campaigns can be PAUSED or ACTIVE.

POST {id} to update supported campaign fields; objective changes are rejected. Updates return {"success": true} after persistence. Set status to ARCHIVED to archive a campaign, or use DELETE {id} to delete it. Archived and deleted campaigns cannot be edited; deletion remains available after archive. The runtime retains their status for inspection. Default campaign lists include ACTIVE and PAUSED; use the JSON-encoded effective_status query parameter to request ARCHIVED or DELETED records explicitly.

GET act_1000000001/campaigns accepts comma-separated fields, limit up to 100, before or after, and summary=true. Cursors and next/previous URLs are bound to the company, incarnation, query and matching campaign state. Restart paging if that state changes. Writes need the write scope and use Fictix's shared idempotency ledger; field selection on writes is limited to id on creation. Read other fields with a separate GET.

The official Python facebook-business 26.0.1 SDK can use the documented FacebookSession.GRAPH base URL and requests session attributes to target this runtime and send X-API-Key. No live vendor token is required. This bounded workflow does not create ad sets, ads, creatives or audiences, serve ads, spend money, produce insights, implement targeting, special categories, lifetime budgets, async/batch Graph requests or OAuth.

Google Analytics 4 events and reports

Use /native/google_analytics_4 with a Fictix runtime key. The company's synthetic property is properties/1000000001, its web measurement ID is G-FICTIX001, and its reporting time zone is UTC. No web traffic is inferred from financial or personnel records: reports begin empty and use only events collected into that company's runtime.

GET v1beta/properties/1000000001/metadata lists the supported dimensions and metrics. POST v1beta/properties/1000000001:checkCompatibility checks requested fields. Supported dimensions are date, eventName, pagePath, pageLocation, hostName, pageTitle and platform; metrics are eventCount, totalUsers and screenPageViews. User counts use distinct web client instances, including normalization of the documented GA client-cookie form.

Send a web Measurement Protocol payload to POST debug/mp/collect?measurement_id=G-FICTIX001 to validate without collecting:

{
  "client_id": "123456789.1234567890",
  "events": [{
    "name": "page_view",
    "params": {"page_location": "https://sample.test/pricing", "page_title": "Pricing"}
  }]
}

Valid requests return {"validationMessages": []}. To persist the same payload, use POST mp/collect?measurement_id=G-FICTIX001, which returns empty 204 only after the complete batch is saved. Batches accept up to 25 events with up to 25 scalar parameters each. Use a Fictix idempotency key to replay a write safely. Fictix authentication uses X-API-Key; the vendor api_secret query parameter is optional and is not used to authenticate this synthetic interface.

POST v1beta/properties/1000000001:runReport to read the saved events:

{
  "dateRanges": [{"startDate": "7daysAgo", "endDate": "today"}],
  "dimensions": [{"name": "pagePath"}],
  "metrics": [{"name": "screenPageViews"}, {"name": "totalUsers"}],
  "orderBys": [{"metric": {"metricName": "screenPageViews"}, "desc": true}],
  "limit": "100"
}

One date range is supported, with absolute dates or NdaysAgo, today and yesterday. Use dimensionFilter with exact, begins-with, ends-with, contains or in-list matches; bounded AND, OR and NOT groups are supported. Ordering uses requested columns, and offset/limit are int64 decimal strings. rowCount describes all matching groups before pagination. batchRunReports accepts up to five requests. All report, compatibility and debug-validation POSTs require only read; collection requires write. Counts are available immediately in this runtime, so a separate report can verify collection.

This is a bounded web workflow. Invalid or unsupported collection fails with HTTP 400 and makes no changes; Google's upstream collector can instead return 2xx and discard invalid events. Fictix always enforces the preceding 72-hour timestamp window, even with RELAXED validation. App streams, User-ID identity, geolocation, consent and advertising attribution, session/engagement/revenue metrics, custom definitions, realtime, pivots, cohorts, metric filters, quota simulation and OAuth are outside this scope. Metadata advertises only the implemented fields.

The official google-api-python-client 2.200.0 REST discovery client is verified for metadata, reports, batch reports and compatibility using the published v1beta Discovery document and its public endpoint/HTTP transport options.

Use /native/google_ads/v25 with a Fictix runtime key. Start with GET customers:listAccessibleCustomers; the generated company owns the synthetic account customers/1000000001, with USD currency, UTC time zone and testAccount: true. Campaigns and budgets start empty.

POST customers/1000000001/campaignBudgets:mutate with an operations array. A budget create accepts name, a positive int64 decimal string amountMicros, and shared daily standard-delivery settings. Then POST campaigns:mutate under the same customer with a campaign create containing name, campaignBudget, advertisingChannelType: "SEARCH", manualCpc: {}, an explicit containsEuPoliticalAdvertising enum and optional status: "PAUSED" or "ENABLED". The response returns resource names; responseContentType: "MUTABLE_RESOURCE" also returns mutable fields. Each batch of up to 100 operations is atomic. validateOnly: true checks the batch without persisting it.

POST googleAds:search or googleAds:searchStream with a GAQL query, for example:

SELECT campaign.id, campaign.name, campaign.status, campaign_budget.amount_micros
FROM campaign WHERE campaign.status != 'REMOVED' ORDER BY campaign.id

These POST endpoints need only the read scope. Supported resources are customer, campaign and campaign_budget, including related account/budget fields. Queries support explicit fields, one = or != predicate, one ordering and a positive LIMIT. Search uses v25's fixed 10,000-row pages, opaque nextPageToken, and optional searchSettings.returnTotalResultsCount or omitResults. pageSize is rejected. Page tokens are bound to the company, incarnation, query, settings and matching state. SearchStream returns the published JSON array envelope in one response. Summary rows are unsupported.

Update with an operation containing update and an exact camel-case updateMask. Budget updates accept name and amountMicros; campaign updates accept name, status, campaignBudget and containsEuPoliticalAdvertising. A remove operation marks a resource REMOVED; a budget cannot be removed while a non-removed campaign references it. Independently query the resource to verify every mutation, and use the same idempotency key for a retried write.

This is a bounded REST interface. It does not claim Google Ads gRPC SDK support, serve ads, bill an account, fabricate spend or traffic, implement metrics, segments, ad groups/ads, temporary IDs, partial failures, manager delegation, OAuth, other campaign types or every upstream error detail. Unimplemented fields and operations return explicit errors.

The official google-api-python-client 2.200.0 REST discovery client is verified against these routes using the published v25 document, its public client_options.api_endpoint override and a Fictix-authenticated HTTP transport.

Justworks company and personnel

Use /native/justworks/v1 for company/member reads and job, department and manager updates. GET /company supplies the department IDs used in PATCH /members/{member_id}. The PATCH body accepts job_title, department_id and manager_id; success returns empty HTTP 204 after the canonical employee record is saved. References must exist in the same company. Self-management and reporting cycles return HTTP 422 without partial changes. Names, job titles, department and manager relationships remain consistent with the other HR providers. Existing department IDs survive moves out of a department.

Member lists return items and an optional next_cursor. Paging defaults to 100 rows and accepts limit up to 100. Filters include status=active or status=terminated, plus updated_at and its _gt, _gte, _lt, _lte and _ne date variants. Cursors are bound to the company incarnation, query and roster state; restart paging after changing the roster. IDs are stable within the company. Absent source creation/update times use the synthetic 2000-01-01T00:00:00Z baseline.

The implementation is checked against the OpenAPI 1.32.5 document embedded in Justworks' published API reference. It covers legal/preferred names, work emails, active status and known employment dates. It does not implement member creation or onboarding, payroll, paystubs, deductions, compensation, sensitive identity fields, benefits, offices, custom fields, OAuth flows or webhook delivery. Job and reporting-line updates have no payroll or payment effects.

SAP business partners

Use /native/sap/sap/opu/odata/sap/API_BUSINESS_PARTNER as the OData v2 base. A_BusinessPartner, A_Customer and A_Supplier support JSON list and single reads with SAP d/results envelopes. Generated customers and vendors have stable master-data IDs and matching customer or supplier references. The partner's to_Customer and to_Supplier navigation properties resolve those existing roles and can be expanded. Names reflect canonical records.

Create a standalone organization with POST A_BusinessPartner and {"BusinessPartnerCategory":"2","OrganizationBPName1":"Example business"}. Category 1 creates a person and requires LastName; FirstName is optional. The implemented grouping is the synthetic 0001. Creation returns HTTP 201, the assigned BusinessPartner and a Location header. Use PATCH A_BusinessPartner('ID') for name, search-term and language updates; success returns empty HTTP 204. An optional If-Match header checks the ETag returned by GET and rejects stale updates with HTTP 412. Fictix idempotency prevents duplicate creates. New partners have no customer or supplier role; these writes do not create financial transactions.

Queries support $top up to 1000, $skip, $inlinecount=allpages, $count, supported-property $select, one string eq or ne predicate and one $orderby property. Default pages contain up to 100 records and include __next when more remain; explicit $top limits the total returned rows. Only JSON is supported. Unsupported query syntax fails explicitly.

The workflow follows SAP's published Business Partner metadata. SAP Cloud SDK clients can use public setBasePath, addCustomHeaders and skipCsrfTokenFetching options with a Fictix API key. SAP session cookies and CSRF token negotiation are unavailable. This subset does not implement deletion, deep inserts, role creation, addresses, tax or bank information, company codes, sales or purchasing areas, batch, metadata/XML, SOAP, payroll, invoices or other ERP APIs. Existing customer/vendor name updates remain visible through other native providers without changing their ledger records.

Workday workers and check-ins

Use /native/workday/staffing/v7 as the base for the implemented Staffing v7 REST workflows. Worker list and single reads expose canonical worker names, employee IDs, work contacts and business titles. Worker WIDs are stable; single reads also accept Employee_ID=.... Lists default to 20 rows, accept limit up to 100 and offset, and exclude terminated employees unless includeTerminatedWorkers=true. Case-insensitive search matches name or worker ID, with space-separated terms combined using OR.

For a returned worker ID, /workers/{ID}/checkIns and /workers/{ID}/checkInTopics support create, list, read, partial update and delete. Creation and ordinary PATCH requests use multipart form data containing one jsonData part with Content-Type: application/json. For example, the check-in JSON part is {"date":"2026-09-06","description":"Weekly review"}; a topic requires name. The response is JSON. Check-ins can reference existing topics through associatedTopics: [{"id":"..."}]; topics can reference check-ins through associatedCheckIns. Reads resolve both sides of those links from persisted records. DELETE removes the resource and its links and returns HTTP 200 with an empty data collection.

Archive and restore use PATCH .../{subresourceID}?type=archive with an ordinary JSON body {"archive":true} or {"archive":false}. Only the creating Fictix credential can edit, archive or delete a check-in or topic. privateNotes are returned only to that credential and are omitted from generic record materialization. This workflow does not associate credentials with employees, so me and editing as a participant are unavailable. Standard Fictix idempotency applies to normalized multipart JSON, independent of its boundary.

The implementation follows the published Staffing v7 OpenAPI specification for these operations. It does not implement attachment uploads, other subresource reference IDs, supervisory visibility, metadata responses, tenant-prefixed paths, SOAP, hiring, payroll, compensation or job changes. Check-in writes do not alter employment or financial records. Unsupported fields and query options return errors.

Use /api/v1/orgs/{slug}/native/adp as the API base URL, with a Fictix API key. Writes require Idempotency-Key. This workflow follows ADP's published Workforce Now guide and official request/response samples. These are documentation and wire-example checks; an official SDK or complete OpenAPI conformance is not claimed.

GET /hr/v2/workers and GET /hr/v2/worker-demographics, including individual /{associateOID} reads, return canonical employee names, work email, job title, hire dates, department and manager references, and active/terminated status. Each worker has distinct stable associate, employee and position identifiers. Sensitive demographic fields, compensation and payroll histories are omitted.

Lists support $top from 1 to 100, defaulting to 50, and nonnegative $skip. Reads after the last record return an empty 204. $select supports the implemented nested worker fields. A single $filter equality can select by worker ID, position ID, manager position ID, assignment status, or department code/type. count=true on /workers reports the unfiltered population in meta.totalNumber, following ADP's documented limitation. The only supported role is Practitioner. Unsupported queries, historical dates, asynchronous preferences and sorting options return errors.

POST /events/hr/v1/worker.legal-name.change accepts one event containing data.eventContext.worker.associateOID and data.transform.worker.person.legalName. It updates givenName, familyName1, middleName and nickName. The completed event response is returned only after the canonical employee change persists. Subsequent ADP and other personnel provider reads reflect the change; retries with the same key replay the stored response. Invalid fields or unknown workers leave state unchanged.

Onboarding, termination, scheduled changes, payroll, compensation, addresses, government identifiers, birth dates, code tables, photos, metadata endpoints and event-notification delivery are outside this workflow. No live ADP requests or financial changes occur.

TriNet HR Platform

The trinet native base implements the public HR Platform Core API, formerly Zenefits, for reading a generated company's personnel and organization. This is separate from TriNet PEO. Use your Fictix X-API-Key and replace the upstream https://api.trinet.com base with your company's /native/trinet base.

Start with GET core/companies or GET core/people. The response contains data.data, data.next_url, object: "/meta/response", numeric status: 200 and the published string error: "null". A detail request such as GET core/people/{id} contains the person directly in data. Follow returned company, department, manager, subordinate and employment URLs within your Fictix company. IDs are numeric strings; a person's API id is distinct from employee_number.

Supported routes are company, people, department and employment lists/details, company people/departments, department people, and person subordinates/employments. Lists default to 20 rows, accept limit up to 100, and use exclusive starting_after or ending_before object IDs. Follow next_url for subsequent pages. Pagination IDs must belong to the current filtered collection; a roster change can invalidate one. Results are ordered by numeric API ID.

People support exact company, department, manager, first_name, last_name and status filters. Company lists accept name; departments accept company and name; employments accept person. Unknown filters are rejected.

includes takes space-separated paths, for example includes=company.departments department.company manager employments.person. Expandable fields are company departments; people company, department, manager, employments; department company; and employment person. Dotted paths may be three levels deep, with at most ten paths and 2,000 rendered records. Expanded lists use the default 20-row page and provide a next_url. Other relationships remain references that you can follow separately.

These reads reflect canonical personnel changes made through supported HR integrations such as Justworks. Each employee has one current employment projection with known hire/termination dates and employment type when available. No past employment, compensation, bank, tax, address, benefit or demographic facts are invented. Roster members default to active unless canonical status or active=false indicates otherwise. Department identity derives from its case-folded canonical label and changes when the label is renamed.

PEO, payroll, Core writes, locations, installation/subscription flows, OAuth and webhooks are outside this workflow. Follow the returned next_url until it is null; the final page follows the published pagination guide.

Sources: Core people, companies, departments, employments, pagination, and inline expansion.