How to connect Sage Business Cloud Accounting to API2Cart?
This guide explains how to connect Sage Accounting to API2Cart. Sage Business Cloud Accounting, which Sage now calls simply Sage Accounting, uses OAuth 2.0: you register your own app with Sage, authorize it once against your Sage business, and pass the resulting credentials to a single API2Cart call.
That call needs three values — sage_client_id, sage_client_secret and sage_refresh_token — and, optionally, a fourth one, sage_business_id. Steps 1–4 below show where each one comes from.
What you need to connect Sage Accounting
- A Sage Accounting business and the login of a user of that business. This user authorizes your app in Step 4.
- A Sage Developer account in Sage Developer Self Service. It is free, and you can sign up with GitHub or an email address. It is used only to register the app and get its credentials: it cannot sign in to Sage Accounting or authorize the app.
- A callback URL — the address Sage sends the browser to, together with an authorization code, after the user allows access. It must be a publicly accessible page that you control and that can receive these requests, for example a page of your website or app. For a one-time setup, you can use Postman and its callback URL instead (see Step 1).
No Sage business yet? Use a free trial
Sage Accounting has no sandbox, but you can sign up for a free 30-day trial business — at the time of writing only in the United Kingdom, on the Accounting Start, Standard and Plus plans, while Canada and Ireland are listed as unavailable (see the trial links in Sage's Set up the Basics guide). For development, Sage can extend a trial to 12 months through the Extend your Sage Business Cloud Accounting Trial form. Keep in mind that the data available through the API depends on the Sage Accounting plan of the business.
Step 1: Create an app in Sage Developer Self Service
Sign in to Sage Developer Self Service and click Create App. Fill in the app details and click Save:
- App Name — Sage Accounting users see it when they authorize the app, so choose a name they will recognize.
- Email Address — a contact address for the app. Required.
- Homepage URL — optional.
- Callback URLs — at least one, one URL per line. Enter the
https://address of the public page that will receive the authorization code. The value is case-sensitive and must match theredirect_uriyou use in Step 4 character for character.
For convenience, you can complete Step 4 in Postman instead of on your own page. In this case, add the Postman callback URLs that Sage lists in its authentication guide: https://www.postman.com/oauth2/callback for the Postman app and https://oauth.pstmn.io/v1/browser-callback for Postman in a browser.
Step 2: Copy the Client ID and Client Secret
Click the name of the new app to open its page. The App Credentials block holds the Client ID and the Client Secret: click Show to reveal a value, or the clipboard icon next to the field to copy it. You need both values to authorize the app and to connect Sage Accounting to API2Cart. The App Details block on the same page lets you edit the name and the callback URLs later.
A Sage Client ID consists of two identifiers separated by a slash, for example xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. Copy the whole value, including the part after the slash: Sage rejects a truncated Client ID, and API2Cart then returns an error that names all three credentials (see Troubleshooting below).
Step 3: Choose the scope
Sage Accounting has only two OAuth scopes, and each one applies to the whole token — there are no per-resource permissions. You pass the scope in the authorization URL in Step 4.
| Scope | Access | When to choose it |
|---|---|---|
full_access |
Read and write | Recommended. Required for every method that creates, updates or deletes data. |
readonly |
Read only | Your integration only reads data, such as lists of records. Sage rejects write requests made with this token. |
The scope is not the only limit. Sage also applies the access rights of the user who authorizes the app in each business — for example, Full Access or Read Only, which the business owner sets under Settings > Manage Users in Sage Accounting. API calls cannot do more than that user can, so authorize the app as a user who has the rights your integration needs.
Step 4: Authorize the app and get a refresh token
This is a one-time OAuth 2.0 authorization code flow. First, build the authorization URL from your Client ID, a callback URL registered in Step 1 and the scope from Step 3, and join the lines below into one:
https://www.sageone.com/oauth2/auth/central?filter=apiv3.1
&response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://example.com/callback
&scope=full_access
&state=RANDOM_STRING
URL-encode the parameter values: the slash in the Client ID becomes %2F. The state parameter is optional but recommended — Sage returns it unchanged, so you can check that the response belongs to your request. If you know the country of the business, you can add country=gb (or ca, ie) to skip the country selection; it must match the country the business is registered in.
Open the URL in a browser. Sage asks you to sign in with the login of a Sage Accounting business user — not your Sage Developer account — and may ask for a one-time verification code. Choose the country of your business if asked, review the access request and click Allow. Sage then redirects the browser to your callback URL with the authorization code in the address bar:
https://example.com/callback?code=AUTHORIZATION_CODE&country=GB&state=RANDOM_STRING
Take the code from the request your callback page receives or from the browser's address bar. The code works only once and expires after 60 seconds, so exchange it for tokens right away:
curl -X POST https://oauth.accounting.sage.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
--data-urlencode "redirect_uri=https://example.com/callback" \
--data-urlencode "client_id=YOUR_CLIENT_ID" \
--data-urlencode "client_secret=YOUR_CLIENT_SECRET"
Use the code exactly as it appears in the address bar, because it is already URL-encoded there; if your callback page gives you the decoded value, pass it with --data-urlencode instead of -d. The redirect_uri must be the same callback URL as in the authorization URL, without any extra parameters.
The response contains an access_token, valid for 5 minutes, and a refresh_token, valid for 31 days. Copy only the refresh_token — it is the last value you need to connect Sage Accounting to API2Cart, which obtains access tokens by itself.
Alternatively, Postman can run this whole step for you. In a new request, open the Authorization tab, select OAuth 2.0 and fill in the new token settings:
- Grant Type — Authorization Code.
- Callback URL — the Postman callback URL that you registered in Step 1.
- Auth URL —
https://www.sageone.com/oauth2/auth/central?filter=apiv3.1. - Access Token URL —
https://oauth.accounting.sage.com/token. - Client ID and Client Secret — the values from Step 2.
- Scope —
full_accessorreadonly(Step 3); State — any value. - Client Authentication — Send client credentials in body.
Click Get New Access Token, then sign in to Sage Accounting and allow access as described above. Postman exchanges the code by itself and shows the token details: copy the refresh_token. Then delete the token in Postman (Manage Tokens), because Postman refreshes tokens automatically by default, and a refresh would invalidate the token you pass to API2Cart.
Step 5: Connect Sage Accounting to API2Cart
Now add the connection in API2Cart — in the dashboard (Add Connection, Integration Type: Accounting, Integration: Sage Accounting), or with the connection.add method of the Accounting API, where integration_id is SageAccounting. Both use the same parameter names:
sage_client_id— the Client ID from Step 2. Required.sage_client_secret— the Client Secret from Step 2. Required.sage_refresh_token— the refresh token from Step 4. Required.sage_business_id— optional: the default business for requests that do not pass their ownorganization_id(see the next section).sage_access_token— optional; leave it empty, because an access token expires after 5 minutes and API2Cart requests its own.
By default, API2Cart checks the credentials with Sage before it saves the connection, so a wrong value is reported right away. A successful call returns a connection_key, which every subsequent accounting API call for this connection must include. Full request formatting is documented in the Accounting API reference in your API2Cart dashboard.
Working with several Sage businesses
One authorization covers every business the Sage user has access to, so a single connection can work with all of them. Without sage_business_id, API2Cart works with the user's lead business — in Sage terms, the first business the user created. To work with another business, get the IDs of all available businesses with organization.list (the one used by default is marked as default), then pass the ID as organization_id in a request, or save it as sage_business_id with connection.update to make it the default.
Sage notes that the lead business can change, for example when the first business is deleted. If the connection must always point to the same business, set sage_business_id.
Keeping the refresh token valid
Sage rotates refresh tokens: every time API2Cart refreshes the access token, Sage issues a new refresh token, and the previous one stops working immediately. API2Cart stores the new token itself. This has two consequences:
- Do not reuse the token you passed to API2Cart. If you refresh the same token in your own code or in Postman, even automatically, Sage invalidates the copy that API2Cart holds, and the connection stops working.
- Keep the connection in use. A refresh token expires 31 days after it was issued. API2Cart refreshes it only while it calls Sage for this connection, so a connection that makes no requests for 31 days loses access.
If the token has become invalid, repeat Step 4 and pass the new refresh token with connection.update. Send only sage_refresh_token and keep the same connection_key — there is no need to create a new connection.
Sage API limits
Sage applies its own limits to each app, shared by all connections that use it, independently of API2Cart: 1,296,000 requests per day and up to 150 concurrent requests.
Troubleshooting
Most problems show up right when you connect Sage Accounting to API2Cart or authorize the app, and they usually come down to one of these:
Some parameters are invalid! Please check your 'sage_client_id' and 'sage_client_secret'.— Sage did not accept the app credentials: the Client ID or the Client Secret is wrong or belongs to another app. Copy both again from App Credentials (Step 2).Some parameters are invalid! Please check your 'sage_refresh_token'.— the refresh token has expired, has been revoked, or has already been used, for example refreshed outside API2Cart. Repeat Step 4 and pass the new token withconnection.update.Some parameters are invalid! Please check your 'sage_client_id', 'sage_client_secret' and 'sage_refresh_token'.— the values do not have the format Sage expects, most often because the Client ID was copied without the part after the slash. Copy all three values again in full.Sage Accounting business '<business_id>' was not found or is not accessible with the provided credentials. Check parameter 'sage_business_id'.— the ID is mistyped, or the user who authorized the app has no access to this business. Take the ID fromorganization.list, or leavesage_business_idempty to use the lead business.Sage Accounting business information is unavailable. Check the business ID (if set) and OAuth application access.— Sage returned no data about the business. Checksage_business_idif you set it, and make sure the user who authorized the app still has access to the business and has not revoked the app's access.- Sage shows an error instead of the access request, or the token request returns
invalid_grant. During authorization Sage rejects aredirect_urithat does not match a registered callback URL character for character, case included. The token request returnsinvalid_grantfor the same mismatch, and for a code that is older than 60 seconds or has already been used. Check the callback URL, authorize again and exchange the new code at once. - You cannot sign in during authorization. Use the login of a Sage Accounting business user, not the Sage Developer account, and make sure the country you choose, or pass in
country, is the country of the business.