Managing your API access
This page is for the person inside your organisation who owns the Scratch Power integration. The good news: most of what you'll do here is point-and-click in the Scratch Power web portal (your normal admin dashboard).
The page is laid out in two layers. Each task has a portal walkthrough first — that's for everyone, no code needed. Then an "Or via the API" subsection — that's only for engineers who want to script the same thing from their own systems. If you're non-technical you can ignore the API subsections entirely; the portal does everything they do.
A quick recap: what you have to keep safe
When you signed up to integrate, Scratch Power emailed you four pieces of information. Together they let your software prove who it is when it talks to Scratch Power. They come in two pairs — one pair identifies the application, the other identifies the user that application runs as.
Pair 1 — identifies the application
| Piece | What it is | Who uses it |
|---|---|---|
| Client ID | A short public name like acme-mobile-app. Not secret. | Your software, on every request it sends to Scratch Power. |
| Client secret | A long random string. Secret — treat like a password. | Your software, on every request it sends to Scratch Power. Paired with the Client ID. |
Pair 2 — identifies the user inside Scratch Power
| Piece | What it is | Who uses it |
|---|---|---|
| Username | The login name of your "integration user" (e.g. acme-integration). | Your software, on every request it sends. |
| Password | The integration user's password. Secret. | Your software, on every request it sends. |
You also got your organisation code (e.g. ACME) and, for the
staging environment, a list of test meter numbers —
see Testing for that side of things.
The Client ID / Client secret identify which application is calling us (your mobile app, your point-of-sale, your batch importer). The Username / Password identify who inside your organisation the calls run as — whose money is deducted on a purchase and what they're allowed to do. Two pairs because the two questions — "which app?" and "as whom?" — are independent.
The two things that go wrong
There are really only two problems that bring people to this page:
- "I've lost my client secret" or "My client secret has leaked" → you need to rotate the secret. See How to rotate your client secret below. This is the recommended path — almost always the right answer.
- "My integration user has forgotten their password" → you send a password reset link to them. See How to reset your integration user's password.
There's also a third, less common option — creating a brand-new API client from scratch. Most people don't need this; you'd only do it when you're adding a second, separate integration (e.g. a new mobile app on top of your existing system). Rotation is better than re-creation when you're trying to recover an existing integration. See Creating a new API client.
Before you start: do you have the right permissions?
The screens you'll use live inside the Administration section of the portal. Whether you can see them depends on the permissions your user has been granted.
The simplest test: sign in and look at the left-hand menu. If you can see Administration → Auth Clients and Administration → Actors, you have what you need. Skip to the next section.
If those menu items are missing, you need one of the permissions in the table below. Ask an admin in your organisation to grant the relevant one, or to do the steps for you.
| Permission name (in the portal) | What it unlocks | Used for |
|---|---|---|
| Manage Auth Clients | Shows the Administration → Auth Clients menu item and all its buttons (create, rotate, delete). | Rotating a client secret, creating a new API client. |
| Manage Actors | Shows the Administration → Actors menu item and full user management (create, edit, delete, password reset). | Resetting an integration user's password. Also covers other user-management tasks. |
| Reset User Credentials | Shows the Send Password Reset Link button on a user's detail panel, without granting the broader Manage Actors privilege. | Resetting an integration user's password — narrower, for support staff who shouldn't manage users fully. |
(For engineers checking permissions in code: these correspond to
ROLE_MANAGE_AUTH_CLIENTS, ROLE_MANAGE_ACTORS, and
ROLE_RESET_USER_CREDENTIALS respectively. Either of the last two
satisfies the password-reset flow.)
Permissions are granted via Administration → Profiles. If your org has a "Profiles" admin, that's who to ask. The in-portal help page is at Help → Administration → Profiles.
- Production: app.scratchpower.com
- Staging (test): app.staging.scratchpower.com
You log in with your normal portal username and password — not with your integration user. The integration user's credentials are only for your software to use; humans log in with their own accounts.
How to rotate your client secret (recommended)
Rotating means generating a brand-new client secret and throwing away the old one. The new secret is shown once on screen, you copy it, you (or your engineer) put it into the software's configuration, and the software starts using it. After that, the old secret stops working — instantly — and every request to the API has to use the new one.
Rotate when:
- You've lost your current secret and need a working one.
- You suspect the secret has leaked (someone emailed it, pasted it in Slack, committed it to git, etc.).
- It's been a long time and you're cleaning up as part of a routine security check.
- An engineer who had production access has left the company.
Step by step:
- Sign in to the portal at app.scratchpower.com (or app.staging.scratchpower.com if you're working in the test environment).
- In the left-hand menu, open
Administration → Auth Clients.
The page will show one card per integration. Each card has a Client ID at the top (likeacme-mobile-app). - Find the card for the integration whose secret you want to rotate. Click anywhere on the card — a panel slides in from the right with the client's details.
- Scroll to the bottom of that panel. You'll see a red Rotate Secret button.
- Click Rotate Secret. A confirmation dialog appears: "Rotate Client Secret? This will invalidate the current secret. Any applications using this client will need to be updated with the new secret." Click Confirm.
- The new secret is displayed inline, masked behind dots. Click the eye icon to reveal it, then click Copy Secret. The secret is now in your clipboard.
- Hand the new secret to whoever maintains your software so they can update its stored credentials. If that's you and you know how, paste it where the old secret was stored — that's usually environment variables on your servers, or a secrets manager like AWS Secrets Manager, 1Password, or Vault. The secret is shown once on screen and never again — don't navigate away until it's saved somewhere durable.
- The engineer then restarts or redeploys the software so it picks up the new secret. Until they do, every request the software sends will fail because it's still trying the old (now-dead) secret.
Steps 1–8 are the complete portal walkthrough. The Or via the API subsection that follows shows the same operation as a REST endpoint — useful if you're scripting rotation from CI or a runbook. If you've already finished the portal steps above, skip past it to the next section.
Or via the API
Endpoint: PATCH /clients/{client_id}/reset
Auth: Bearer access token, caller must have Manage Auth Clients (ROLE_MANAGE_AUTH_CLIENTS).
Request body: none.
Path parameters:
| Name | Type | Required | Description |
|---|---|---|---|
client_id | string | yes | The Client ID whose secret should be rotated. Must already exist under the caller's organisation. |
Example:
curl -X PATCH https://api.scratchpower.com/clients/acme-mobile-app/reset \
-H "Authorization: Bearer $TOKEN"{
"secret": "59ceadf8-bn4b-46e2-93b2-3efafedcab1c"
}Response fields (200 OK):
| Field | Type | Always present | Description |
|---|---|---|---|
secret | string | yes | The newly-generated client secret. Shown only in this response — the platform stores a one-way hash, so this value cannot be retrieved later. UUID v4 format (36 chars). Treat as a password. |
Errors:
| HTTP status | When | What to do |
|---|---|---|
401 Unauthorized | Your access token is missing, malformed, or expired. | Refresh the token via POST /v1/auth/refresh and retry. |
403 Forbidden | The authenticated user lacks Manage Auth Clients. | Ask an org admin to grant it, or run the rotation in the portal instead. |
404 Not Found | The client_id doesn't exist under the caller's organisation. | Auth clients are scoped per organisation; double-check the value. Cross-org rotation isn't allowed on this endpoint. |
500 Internal Server Error | Unexpected platform error. | Retry once with the same request; if it fails again, contact support with the response's X-Request-Id header. |
The instant you confirm the rotation, the old secret stops working. Plan to do this at a moment when a brief authentication failure is acceptable — or coordinate with your engineers so the new secret is deployed within seconds of the rotation. Tokens that the software has already received keep working for ~1 hour (until they naturally expire), but no new logins will succeed with the old secret.
Scratch Power stores only a one-way hash of your client secret, not the secret itself. Even Scratch Power staff cannot retrieve the original — so if you've lost it, rotation is the only way forward. The new secret is displayed once on screen at the moment you click Rotate Secret; capture it then.
If you'd like to see screenshots and the full reference for this screen, the in-portal help page is at Help → Administration → Auth clients.
How to reset your integration user's password
The integration user is the person-shaped account inside Scratch Power that your software logs in as. If that account's password has been lost or you want to rotate it, you don't type a new password yourself — you send a password reset link to the user's registered phone number and email. They click the link, set a new password (and a PIN — a short numeric code used by the portal for a few sensitive operations), and you put that new password into your software.
Step by step:
- Sign in to the portal at app.scratchpower.com (or app.staging.scratchpower.com).
- In the left-hand menu, open
Administration → Actors.
(An "actor" is what we call any user or system account inside your organisation — the term covers both humans and the integration user your software logs in as.) - Find the row for your integration user (usually named something
like
acme-integrationordealer). Click the row to open the edit panel. - Scroll to the Account actions section near the bottom.
- Click Send Password Reset Link.
- Confirm the action. A toast at the top right reads "Password reset link sent via SMS and email".
- The integration user receives both an SMS and an email with a one-time setup link. They click it, choose a new password and PIN, and that's it.
- Once they've set the new password, hand it to your engineer (or update it yourself if you maintain the software) so the software's stored password is refreshed. Then a restart / redeploy picks up the change.
The link works once and expires after 24 hours. If your user doesn't click it in time, repeat step 5 to issue a fresh one.
The reset link goes to the phone number and email stored on the integration user's profile. If those have changed (e.g. the person who set up the integration has left), edit the actor first and save the new contact details before clicking Send Password Reset Link. Otherwise the link goes somewhere you can't read.
The portal steps above are the complete flow. The Or via the API subsection that follows is for engineers who want to trigger the same reset from a script. Non-technical readers can skip to the next section.
Or via the API
Endpoint: POST /api/admin/users/{id}/send-reset-link
Auth: Bearer access token, caller must have Manage Actors (ROLE_MANAGE_ACTORS) or Reset User Credentials (ROLE_RESET_USER_CREDENTIALS). Platform admins can issue resets cross-org; org-scoped admins are restricted to actors in their own organisation.
Request body: none.
Path parameters:
| Name | Type | Required | Description |
|---|---|---|---|
id | integer (int64) | yes | The numeric actor ID of the user whose password should be reset. Find it under Administration → Actors in the portal, or via GET /api/admin/users?search=<username> (returns a list including each actor's id). |
Alternate path: POST /api/admin/users/{id}/reset-password — same handler, same behaviour, kept for backwards compatibility with the legacy URL.
Example:
curl -X POST https://api.scratchpower.com/api/admin/users/6/send-reset-link \
-H "Authorization: Bearer $TOKEN"{
"success": true,
"message": "Password reset link sent to the user's email and phone."
}Response fields (200 OK):
| Field | Type | Always present | Description |
|---|---|---|---|
success | boolean | yes | Always true on a 200 response. Present so callers using shared JSON envelope handling can branch uniformly. |
message | string | yes | Human-readable confirmation. Stable string today: "Password reset link sent to the user's email and phone." Don't pattern-match this — the success flag is the contract. |
Errors:
| HTTP status | When | What to do |
|---|---|---|
401 Unauthorized | Access token missing, malformed, or expired. | Refresh the token and retry. |
403 Forbidden | The caller lacks Manage Actors / Reset User Credentials, or the caller is org-scoped and the target actor belongs to a different organisation. | Promote the caller or run the reset from a user inside the target actor's org. |
404 Not Found | No actor exists with the given id. | Verify the ID — the portal shows it in the actor's URL, and GET /api/admin/users includes it on each row. |
500 Internal Server Error | The reset token couldn't be issued or one of the notification dispatches failed unexpectedly. | Retry; if it persists, contact support with the response's X-Request-Id header. |
A 200 confirms the token was issued and the dispatch calls were made. Delivery is asynchronous — the SMS and email leave the queue shortly after the response returns. If neither arrives within a couple of minutes, check the actor's phone_number and email fields under Administration → Actors before reissuing.
If you'd like more detail on managing users in general, the in-portal help page is at Help → Administration → Actors.
Creating a new API client (only when you need a second integration)
This section is for the rare case where you genuinely need a second, separate set of API credentials — for example, you're about to launch a mobile app alongside your existing point-of-sale software, and you want them to have independent client IDs so they can be revoked separately. If you're trying to recover lost credentials, don't do this — rotate the existing secret instead. Rotation keeps your historical audit trail clean and avoids duplicate-client clutter.
Step by step:
- Sign in to the portal at app.scratchpower.com.
- In the left-hand menu, open Administration → Auth Clients.
- Click the + New Client button (top right of the page).
- Fill in the dialog:
- Client ID — a short, human-readable name with no spaces.
Only letters, numbers, hyphens and underscores. Example:
acme-mobile-app. This name is public; pick something descriptive so you'll recognise it later. - Description (optional) — a one-liner explaining what this client is for. Example: "Mobile app API access — iOS & Android". You can change this later from the detail panel.
- Scopes — tick read if the integration needs to read data and write if it needs to make purchases.
- Grant Types — tick the boxes that match how your software signs in. For most integrations you want Password and Refresh Token ticked, the others left unticked. If your engineers told you specific values, follow their lead.
- Access Token TTL (seconds) — how long an issued access
token stays valid before your software has to refresh it.
Default
3600(= 60 minutes). Leave alone unless you have a specific reason. (TTL stands for "time-to-live" — the time the token works for.) - Refresh Token TTL (seconds) — how long a refresh token
stays valid. Default
7776000(= 90 days). Leave alone unless you have a specific reason.
- Client ID — a short, human-readable name with no spaces.
Only letters, numbers, hyphens and underscores. Example:
- Click Create Client. The new secret is shown once, masked behind dots — click the eye icon to reveal it, then Copy Secret.
- Hand the secret (and the new Client ID) to your engineer so they can put it into the new integration's configuration. If you're the engineer: paste it into the new app's environment variables / secrets manager, deploy, and confirm it can log in.
Steps 1–6 are the complete portal walkthrough. The Or via the API subsection that follows shows the same create operation as a REST endpoint — useful for Terraform-style automated provisioning. Non-technical readers can skip past it.
Or via the API
Endpoint: POST /clients
Auth: Bearer access token, caller must have Manage Auth Clients (ROLE_MANAGE_AUTH_CLIENTS).
Content-Type: application/json
Request body fields:
| Field | Type | Required | Default | Description / constraints |
|---|---|---|---|---|
client_id | string | yes | — | The public identifier for the new client. Must match ^[A-Za-z0-9_-]+$ (letters, digits, hyphens, underscores). No spaces. Must be unique within the caller's organisation. Stable for the lifetime of the client — pick something descriptive (e.g. acme-mobile-app). |
scope | string array | yes | — | Which API surface this client may touch. Allowed members: "read", "write". Most integrations need both. At least one element is required. Sent as a JSON array, e.g. ["read","write"]. |
grant_types | string array | yes | — | Which OAuth2 grants this client may use. Allowed members: "password", "refresh_token", "client_credentials", "authorization_code". At least one element is required. For most server-to-server integrations, ["password","refresh_token"] is the right answer. |
access_token_validity | integer (seconds) | no | 3600 | How long an issued access token stays valid. Range: positive integer. Default 3600 (= 60 minutes). |
refresh_token_validity | integer (seconds) | no | 7776000 | How long an issued refresh token stays valid. Range: positive integer. Default 7776000 (= 90 days). |
description | string | no | null | Free-form note, shown on the client card in the portal. Useful for "what is this integration for?" Editable later via PATCH /clients/{client_id}. |
Example:
curl -X POST https://api.scratchpower.com/clients \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"client_id": "acme-mobile-app",
"description": "Mobile app API access — iOS & Android",
"scope": ["read", "write"],
"grant_types": ["password", "refresh_token"],
"access_token_validity": 3600,
"refresh_token_validity": 7776000
}'{
"client": {
"id": 17,
"client_id": "acme-mobile-app",
"scope": ["read", "write"],
"grant_types": ["password", "refresh_token"],
"access_token_validity": 3600,
"refresh_token_validity": 7776000,
"description": "Mobile app API access — iOS & Android"
},
"secret": "1c7f4b2a-5d9e-4cf2-8a3b-72e9a1d4b6c0"
}Response fields (200 OK):
| Field | Type | Always present | Description |
|---|---|---|---|
client | object | yes | The newly-created client. Fields detailed below. |
client.id | integer (int64) | yes | Internal database ID. Stable for the lifetime of the client. Not used for authentication — your software uses client_id for that. |
client.client_id | string | yes | The public identifier you supplied in the request. Echoed back so clients can confirm. |
client.scope | string array | yes | The scopes granted. Echoes the request. |
client.grant_types | string array | yes | The grant types granted. Echoes the request. |
client.access_token_validity | integer (seconds) | yes | Active TTL for access tokens minted with this client. |
client.refresh_token_validity | integer (seconds) | yes | Active TTL for refresh tokens minted with this client. |
client.description | string | null | no | The description you supplied, or null if you omitted it. |
secret | string | yes | The newly-generated client secret. Shown only in this response — store it immediately. UUID v4 format. Treat as a password. |
GET /clients/{client_id} returns the same client object without the secret field, since the platform stores only a one-way hash of the secret. The secret is irretrievable after this response — your only recovery path is rotation (PATCH /clients/{client_id}/reset).
Errors:
| HTTP status | When | What to do |
|---|---|---|
400 Bad Request | Missing required field, client_id doesn't match the allowed pattern, or scope / grant_types arrays are empty or contain unknown members. | Read the error body's param field to identify which field is wrong. |
401 Unauthorized | Access token missing, malformed, or expired. | Refresh and retry. |
403 Forbidden | The authenticated user lacks Manage Auth Clients. | Ask an org admin to grant it, or use the portal. |
409 Conflict | A client with this client_id already exists in your organisation. | Pick a different client_id, or rotate the existing one's secret instead of creating a duplicate. |
500 Internal Server Error | Unexpected platform error. | Retry; contact support with X-Request-Id if it persists. |
Creating a new Auth Client does not create a new integration user — they're independent. A new Auth Client lets a different application talk to the API; the integration user is still whoever the calls run as. If you also need a new integration user (e.g. so the new application's transactions show up under a different account name), create that under Administration → Actors first, then come here.
The in-portal help page at Help → Administration → Auth clients covers the create form in more detail, including a field-by-field reference.
Got completely locked out?
If you've lost the credentials and you also can't sign in to the portal yourself, you'll need a human to help. Email support@scratch-power.com from the address registered to your organisation and explain what you need restored. We'll verify identity out-of-band before issuing fresh credentials. Always include:
- Your organisation code (e.g.
ACME). - Your Client ID (the public one — it's safe to include).
- A description of what you've already tried.
Quick reference
| You want to… | Portal path | API endpoint | Notes |
|---|---|---|---|
| Get a new client secret for an existing client | Administration → Auth Clients → click client → Rotate Secret | PATCH /clients/{client_id}/reset | New secret shown once; old stops working immediately. Recommended for lost or leaked secrets. |
| Reset an integration user's password | Administration → Actors → click user → Send Password Reset Link | POST /api/admin/users/{id}/send-reset-link | SMS + email with a 24-hour reset link. |
| Add a brand-new integration | Administration → Auth Clients → + New Client | POST /clients | Creates a new Client ID + secret. Use only when you genuinely want a second, separate integration. |
| Update what an existing client can do | Administration → Auth Clients → click client → Edit description | PATCH /clients/{client_id} | Description-only edits via UI; scope / grant changes require a Scratch Power admin. |
| Delete an integration | Administration → Auth Clients → click client → Delete Client | DELETE /clients/{client_id} | Permanent. All applications using this Client ID lose API access. |
Every API endpoint above requires a Bearer access token (see
Authentication) and a user with the
relevant permission — Manage Auth Clients for the /clients
endpoints, Manage Actors or Reset User Credentials for the
reset-link endpoint.