Resources
Frequently Asked Questions
Quick answers to the questions partners ask most often when integrating with COUNT. Each answer links to the full documentation when you need more detail.
Still stuck?
Email support@getcount.com with your clientId and a description of the issue — never include your clientSecret.Getting started
What is the COUNT Partner API?+
The Partner API lets your application read and write a customer's accounting data — customers, invoices, transactions, documents, and more — after the user authorizes your app through OAuth. Every request is signed with your app secret and scoped to a single workspace.
How do I get API credentials?+
Create an OAuth app in COUNT Partners to receive a clientId and clientSecret instantly, or submit the access request form for COUNT to provision credentials.
Which API environment does this documentation use?+
All Partner API requests in this documentation target the production environment at api.getcount.com. Production credentials are issued after partner review. Contact support if you need a development sandbox for pre-production testing.
What is the fastest way to make my first API call?+
Follow the quickstart to obtain credentials and a workspace access token, then use Try it or a starter template to send a signed request. The signature generator helps verify your HMAC implementation.
Authentication & signing
Why do I need both HMAC signing and a Bearer token?+
HMAC proves the request came from your registered app (clientId + clientSecret). The Bearer access token proves the end user authorized access to a specific workspace. Data endpoints require both; token exchange routes require signing only.
Why does my signature fail with 401?+
The most common mistake is including /partners in the HMAC path. Sign the path relative to the mount — for example /customers, not /partners/customers. Also verify the timestamp, exact JSON body hash, and that your clientSecret matches the clientId.
What happens when my access token expires?+
Call POST /partners/refresh-user-access-token with your refresh token to obtain a new access token pair. Implement refresh proactively before expiry to avoid failed requests.
What does the user see when connecting my app?+
Users sign in to COUNT and approve access on a consent screen showing your app name and the workspace being connected. Register exact redirect URIs in COUNT Partners before starting the flow.
Using the API
Are identifiers numeric IDs or UUIDs?+
Partner responses always expose UUIDs as id or uuid. Internal numeric database IDs are never returned. Copy the id from the matching list or get call and pass it in path parameters and *Uuid reference fields (vendorUuid, customerUuid, categoryAccountUuid). A numeric id is rejected on many routes and silently ignored on others, so never send one.
What are the rate limits?+
The partner API gate allows 100 requests per minute per clientId; the COUNT CLI and its local MCP server share that budget. A hosted MCP session (api.getcount.com/mcp) gets 120 requests per minute per session. Reports share the global limit, so avoid running more than five in parallel. Some resources (such as Documents uploads) have additional tiers. On a 429, honour Retry-After when present and otherwise back off exponentially (1s, 2s, 4s).
How do list endpoints paginate?+
Use page (1-based) and limit query parameters. Responses include totalRecords and totalPages. The records array key varies by resource — for example data.records for customers and data.transactions for transactions.
How often is the API reference updated?+
The API reference is updated when new partner routes ship in the COUNT API. Each group page shows a last-updated date. Check the Changelog for recent additions.
Why does Try it show a network error?+
Try it sends requests from your browser. It works on developers.getcount.com and localhost when the API allows that origin. On other hosts, use starter templates or run requests from your server.
Should I use the COUNT CLI or remote MCP?+
Use the COUNT CLI with count mcp for Claude Code, Cursor, and custom agents — it handles OAuth loopback login and loads credentials from ~/.count/credentials.json. Use the remote MCP URL (https://api.getcount.com/mcp) for Claude.ai connectors and ChatGPT plugins.
What redirect URI do I register for count login?+
Register http://127.0.0.1:17845/callback on your partner app in COUNT Partners. If you use count login --port, the registered URI must match exactly.
Which field names reference accounts, vendors, customers, and tags?+
accUuid is the bank or cash account a transaction sits in; categoryAccountUuid is the income or expense category on transactions, bill lines, and category changes. Entities use vendorUuid, customerUuid, and projectUuid. Tags are tagUuids — a string array in request bodies, a comma-separated string or array in list filters. List filters also accept accountUuid for accUuid and type for transactionTypes, but prefer the canonical names. Response rows do not always reuse request names: a customer row carries its display name in customer, not name.
Why was my numeric vendorId, tags, or vendors parameter rejected?+
Bill and list routes take UUID fields only, and the legacy numeric spellings return 400 rather than being ignored. Use vendorUuids (comma-separated) instead of vendors on the bill list; vendorUuid, tagUuids, and projectUuid instead of vendorId, tags, and projectId on bill create and update; and categoryAccountUuid instead of categoryAccountId on line items.
What does _partnerWarnings mean on a successful response?+
Some of the fields you sent were not applied. Each warning is { field, reason, message }: reason internal_only means COUNT manages that field itself (for example billId on a transaction update — use the dedicated route instead), and unknown_field means a typo or a field the resource does not have. A 200 or 201 with warnings does not mean every field was saved, so read the array before reporting a write as complete.
How should I run a large bulk import?+
Bulk routes accept at most 100 rows per call; for large historical backfills send about 25 rows per call with roughly two seconds between batches. Each row succeeds or fails on its own, and the batch returns 201 whenever the envelope is accepted — even if every row failed — so read errorCount, map each failed results[].index back to your input, and resend only those rows. A 400 means the envelope itself was invalid, such as more than 100 rows or a missing array.
How do I filter a profit and loss report to one category?+
Look up the account in the chart of accounts, copy its UUID, and pass it as categoryAccount (aliases categoryAccountUuid, or categoryAccountUuids for a comma-separated list) alongside startDate and endDate. Trial balance and balance sheet take accounts or accountUuids the same way. Numeric account ids are not accepted.
How do I add an account, such as a credit card, to the chart of accounts?+
List the account sub-types (GET /partners/account-sub-types, optionally filtered by type such as Liabilities), copy the integer id of the matching row, and create the account with name and that subTypeId — or use the bulk route for up to 100 accounts. Sub-type ids are sparse global ids, so never guess or probe them. Finish the chart of accounts before importing bills or transactions. An account that already has journal entries cannot be deleted; set its status to inactive instead.
Can I export a budget to Excel and import it back?+
Budgets are JSON only — there is no CSV upload. Read the budget grid without actuals, edit it in a spreadsheet keeping accountUuid, periodStart (YYYY-MM-DD), and amount aligned with the grid, then write it back with the bulk cell update on a draft version in batches of about 25 rows (100 at most). Publish the version when it is ready.
MCP connector
How does the MCP connector handle more than one workspace?+
With several authorized workspaces, every read and write tool needs workspaceId (the workspace UUID from COUNT_list_workspaces); with one, it is optional. COUNT_set_active_workspace only changes the default shown by COUNT_auth_status — it does not stand in for workspaceId. Each workspace is a separate set of books, so an agent should ask which workspace the user means rather than query them all and add the results together, unless the user asks to compare or combine them.
Why does COUNT_auth_status show fewer workspaces than I see in COUNT?+
COUNT_auth_status and COUNT_list_workspaces list the workspaces this connection was authorized for on the consent screen, not every workspace your COUNT account can open. You may have selected only some of them, or gained access to more client workspaces after connecting. Treat authorizedWorkspaces and COUNT_list_workspaces as the source of truth; the scope field may be null.
+
Only by reconnecting. The workspace set is fixed at consent, and neither refreshing tokens nor gaining access in the COUNT web app changes it. Disconnect the COUNT connector, connect again, select every workspace you want on the consent screen, then confirm with COUNT_list_workspaces. Firm staff can only authorize workspaces they already have access to in COUNT.
How do I disconnect and reconnect the COUNT connector?+
In your AI app's settings, open Connectors (Claude) or Plugins (ChatGPT), remove COUNT, then add it again with the server URL https://api.getcount.com/mcp. Sign in when redirected to COUNT, select the workspaces to authorize, and approve. The local COUNT CLI server takes its workspace from count login instead, so reconnecting the hosted connector does not affect it.
What does a failed MCP tool call return?+
The result sets isError: true and carries { message, statusCode, responseBody, _mcpRecoveryHint } in content[0].text — there is no field-level errors[] array. 400 is a validation or business rule failure: fix the payload (COUNT_validate_payload checks it without writing) rather than retrying it unchanged. 401 is retried once after an automatic token refresh; if it persists, reconnect. 403 means the workspace is not authorized for this connection, 404 means the UUID is not in that workspace, 429 (type RATE_LIMITED) means back off, and on a 500 quote responseBody.requestId to support instead of retrying blindly.
How does an agent learn the request shape for a COUNT tool?+
COUNT_describe_endpoint takes a tool name and returns the Partner API path it calls, its read-only and destructive flags, a typed summary of its inputs, documented errors and response shape, and whether each field belongs in the query or the body. COUNT_knowledge answers connector and workflow questions, and COUNT_playbooks returns ordered multi-step workflows.
Webhooks
How do I receive webhook events?+
Create a subscription per event type with a public HTTPS callback URL. Only active subscriptions receive deliveries. Optionally set a signing secret to verify X-Webhook-Signature on each POST.
Does COUNT retry failed webhook deliveries?+
Yes — up to 3 attempts with exponential backoff starting at 2 seconds. Each attempt has a 15 second timeout. Return HTTP 2xx promptly; process events asynchronously if needed.
Are webhook deliveries ordered?+
No — deliveries are not guaranteed to arrive in causal order. Design handlers to be idempotent using the delivery id, and upsert resources by UUID from the envelope data.
Partner program & support
How do I get production credentials?+
Complete your integration in Dev, then submit for review through COUNT Partners or the access request form. COUNT verifies redirect URIs, data usage, and security practices before issuing production credentials.
How do I get help with an integration issue?+
Email support@getcount.com with your clientId (never your clientSecret), the endpoint and environment, and steps to reproduce. For product questions about COUNT workspaces, use the Help Center.
What do enterprise customers ask for during diligence?+
Common requests cover TLS, token storage, workspace isolation, webhook verification, rate limits, and data handling. The Security & webhook operations page summarizes our model; contact support for SOC 2 or questionnaire requests.
How are API changes communicated?+
Non-breaking additions ship continuously. Breaking changes receive 90 days notice when possible. Monitor the changelog and subscribe to updates during production review.
