# How to create an OAuth app in Sage Business Cloud Accounting

This guide is for the application owner: the team that builds the integration and configures the
Sage Business Cloud Accounting connector once, for all of its consumers.

You can complete every step here yourself: registering on the Sage Developer Portal is
self-service, with no gatekeeper to wait on before you start. Apideck's own credentials let you
evaluate and test the connector immediately, and going live means registering your own Sage app so
that your consumers authorise your brand rather than ours. That is what the steps below cover.

**Before you start, you'll need:** an account on the [Sage Developer Portal](https://developer.sage.com/accounting),
and access to the [Apideck Dashboard](https://platform.apideck.com/configuration/accounting/sage-business-cloud-accounting)
for this connector.

## 1. Create your developer account and register your app

1. Sign up at [developer.sage.com](https://developer.sage.com/accounting).
2. Follow Sage's [Set up the basics](https://developer.sage.com/accounting/quick-start/set-up-the-basics/)
   quick start to create an application.
3. Give the app the name, description and logo your consumers should see on Sage's consent screen.
   This is the branding they will recognise when they connect.

## 2. Find your Client ID and Client Secret

Sage issues a **Client ID** and a **Client Secret** for the app you just created. Copy both, and
store the secret in your own secret manager as well: treat it like a password rather than something
you can look up again later.

You will paste both values into the Apideck Dashboard in step 5.

## 3. Set the redirect URL

Set your app's redirect (callback) URL to exactly:

```
https://unify.apideck.com/vault/callback
```

This is the only redirect URL the connector uses. Apideck receives Sage's authorisation response
here and exchanges it for tokens on your behalf. A redirect URL that does not match this value
character for character will make Sage reject the authorisation attempt.

## 4. Request account authorization from Sage

Registering the app is not by itself enough to call the live API. From your app in the developer
portal, submit Sage's **account authorization** request for it. Sage reviews and confirms this
manually, and states that confirmation takes 3 to 5 working days, so submit it before the week you
plan to go live rather than on the day.

While you wait, you can keep building: the connector, the unified API and your own code path are all
testable ahead of the confirmation.

Do not confuse this request with a Sage Marketplace listing. The account authorization above is
required to call the live API; a Marketplace listing is a separate, optional distribution step, and
the Overview links to where you apply for one.

## 5. Add the credentials in the Apideck Dashboard

Open the [Apideck Sage Business Cloud Accounting connector settings](https://platform.apideck.com/configuration/accounting/sage-business-cloud-accounting),
enable **Use your own client credentials**, and paste in the Client ID and Client Secret from
step 2. Save.

### Scopes

There is nothing to select. Sage Business Cloud Accounting exposes a single scope, `full_access`,
which the connector requests for you. There is no granular scope list to narrow down, so plan your
consumer-facing consent copy around one all-or-nothing permission grant.

## Connection settings your consumers will meet

The five steps above all happen once, in Sage's portal and the Apideck Dashboard. The two settings
below are different: they live on each individual connection and are chosen per consumer, either by
you during setup or by the consumer when they connect. Both must hold a value before a connection
works, so build them into your onboarding rather than treating them as optional extras.

### Country

**Select country** is a required connection setting, and it must be set *before* authorisation: the
connector sends it as a parameter on its single authorisation URL, which is what routes the consumer
to the right regional Sage sign-in.

The dropdown currently lists seven countries, but only three of them authenticate against this
connector:

| Works | Does not authenticate |
|---|---|
| 🇨🇦 Canada, 🇬🇧 United Kingdom, 🇮🇪 Ireland | France, Germany, Spain, United States |

Sage Business Cloud Accounting does have regions beyond these three, but they run on Sage's older
regional v3.0 API. This connector targets the Global Accounting Core API v3.1, which Sage documents
as serving the United Kingdom, Ireland and Canada. Steer your consumers to Canada, the United Kingdom or
Ireland in your own onboarding copy: a consumer who picks one of the other four will not get past
Sage's sign-in screen.

### Default Company

The Sage Business Cloud Accounting API supports multi-business: one Sage login can have access to
more than one business, so every request has to say which business it is for. Sage uses an
`X-Business` header for this.

The connector exposes a **Default Company** setting (`business_id`) whose options are loaded live
from the businesses the authorised login can see. Apideck then sends the selected business as the
`X-Business` header on every request. You can override it per request by sending an
`x-apideck-company-id` header, which takes precedence over the connection's setting, useful when
one consumer's login legitimately spans several businesses.

![Apideck - Configure business](https://res.cloudinary.com/apideck/image/upload/v1709039159/docs/connectors/sage-business-cloud-accounting/business_id_setting.png)

Two reasons it always has to be set:

- **The setting is required on every connection, not only on logins that can see several
  businesses.** While it is empty the connector treats the connection as incomplete, so it never
  becomes usable. Build your onboarding so nobody stops at "connected" and assumes they are done.
- Sage's own fallback, when no `X-Business` header is sent, targets the user's *lead* business, the
  first business that user created, which changes if that business is deleted. That can be the wrong
  set of books, and which business is the lead one is not under your control. Sage returns an
  `X-Business` response header on every response except `/businesses` and `/user`, so the business a
  request actually applied to is always visible.

Sage documents the header and the lead-business fallback under
[Multi Business](https://developer.sage.com/accounting/docs/v1.0.0/guides/learning/key-concepts/multi-business).

## Reference: OAuth and API endpoints

Useful if you need to allow-list hosts or fill in a security questionnaire. Apideck performs all of
these calls for you.

| Purpose | Endpoint |
|---|---|
| Authorisation | `https://www.sageone.com/oauth2/auth/central` |
| Token and refresh | `https://oauth.accounting.sage.com/token` |
| Revoke | `https://oauth.accounting.sage.com/revoke` |
| API base URL | `https://api.accounting.sage.com/v3.1` |

Token and revoke requests are sent as `application/x-www-form-urlencoded`. There is one API base URL
for every supported country. Apideck refreshes access and refresh tokens automatically for as long
as the connection stays in use.

## FAQ and troubleshooting

**`400` with `error=invalid_client` from the token endpoint.** The app credentials are wrong. Re-copy
the Client ID and Secret from the Sage Developer Portal into the Apideck Dashboard, and check you
have not pasted a trailing space.

**`400` with `error=invalid_grant` from the token endpoint.** The authorisation code or refresh token
has expired or was already used. Have the consumer reconnect to start a fresh authorisation.

**A connection authorises but never becomes usable.** Check **Default Company** first: see the
section above. The connector treats a connection with that setting empty as incomplete, on
single-business logins as much as multi-business ones.

**Every request returns `403 Forbidden`.** The Sage user who authorised the connection does not have
permission to authorise applications. The connection needs re-authorising by the Sage account holder
or by a user who holds that permission.

**Authorisation fails before the consumer reaches the consent screen.** Check the country setting
(see Country above) and the redirect URL (step 3) first: those are the two settings Sage validates
before it will show a consent screen.

**`429 Too Many Requests`.** Sage applies its rate limits per app, so all of your consumers share
your app's budget (the limits themselves are listed on the connector's Overview). If your volume
genuinely needs more headroom, Sage takes increase requests at `sbc-accounting-api-developers@sage.com`.

**Still stuck?** Contact [Apideck Support](https://help.apideck.com/en/articles/7774658).

## References

- [Sage Accounting developer portal](https://developer.sage.com/accounting)
- [Set up the basics (quick start)](https://developer.sage.com/accounting/quick-start/set-up-the-basics/)
- [Multi Business and the `X-Business` header](https://developer.sage.com/accounting/docs/v1.0.0/guides/learning/key-concepts/multi-business)
- [Sage API best practices](https://developer.sage.com/accounting/docs/v1.0.0/guides/learning/key-concepts/best-practices)
