OAuth Apps
An OAuth App is a set of machine credentials — a client_id and a client_secret — that a system you control exchanges for an access token. That token authenticates calls into your Paminga instance without anyone signing in and without a password living in your integration's configuration.
Paminga implements the OAuth 2.0 client credentials grant, which is the grant designed for exactly this: server-to-server communication where there is no human at the keyboard.
Use an OAuth App to:
- Make authenticated calls to Paminga's GraphQL API
- Trigger Abandoned Cart Automations
- Trigger Product Recommendation Automations
- Fire Custom Events from your backend
If you want a credential tied to a person rather than to a system, use a Personal Access Token instead.
How It Works
Getting an OAuth App working is two steps, and they're worth keeping distinct in your head because they hit different endpoints:
| What you do | What you get | Endpoint | |
|---|---|---|---|
| Step 1 | Create the App — once, in the interface or through the API | client_id + client_secret | the interface, or /graphql |
| Step 2 | Exchange those credentials for a token — as often as you need | access_token | /oauth/token |
Step 2 is a standard OAuth token exchange, not a GraphQL operation. There is no way to obtain an access token through the GraphQL API, so both endpoints live on the same host and are easy to mix up: /graphql provisions, /oauth/token authenticates.
Create an OAuth App
Go to the OAuth Apps page and click Create OAuth App.
You'll provide:
| Field | Required | Purpose |
|---|---|---|
| Name | Yes | A label so you can recognize this App later — "Shopify Cart Sync," "Data Warehouse Loader." |
| Description | No | What the App is used for. Useful once you have several. |
Click Create OAuth App and Paminga shows you the Client Credentials dialog containing your client_id and client_secret. Copy the secret somewhere safe before you close it.
Paminga stores your client secret hashed, which means we cannot show it to you again — not in the interface, not by support request. The dialog deliberately ignores backdrop clicks and the Escape key so you can't lose the secret by accident. Only the Done button closes it.
If you do lose a secret, rotate it. Rotation gives you a new one.
Your client_id remains visible in the OAuth Apps grid, so you only ever need to safeguard the secret.
Creating an App Through the API
You can also provision Apps from a setup script, an internal admin tool, or your own onboarding flow. Send GraphQL operations to:
POST https://api.paminga.com/graphql
Creating, rotating, and deleting Apps requires a credential belonging to a person — a Personal Access Token or a signed-in session. An OAuth App's own access token is refused with:
OAuth App credentials cannot be managed with a client-credentials token. Sign in as a user to manage OAuth Apps.
That's deliberate. If a machine token could mint fresh credentials, revoking a compromised App wouldn't actually end the compromise — the attacker would simply issue themselves a replacement on the way out. Use a Personal Access Token to provision OAuth Apps.
client_secret comes back on this response and nowhere else, so capture it here.
mutation {
createOauthApp(name: "Warehouse Loader", description: "Nightly data sync") {
client_id
client_secret
name
description
created_at
}
}
name is required and must not be blank; both name and description cap at 255 characters.
However you created the App, you now have credentials — not a token. Exchanging them turns them into one.
Exchange Your Credentials for an Access Token
Post your credentials to Paminga's token endpoint:
POST https://api.paminga.com/oauth/token
curl -X POST https://api.paminga.com/oauth/token \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=*"
You get back a bearer token:
{
"token_type": "Bearer",
"expires_in": 31536000,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp..."
}
If your Paminga account is hosted in the EU, post to https://api.eu.paminga.com/oauth/token instead. See EU Data Residency.
Token Lifetime
Client credentials tokens are valid for 365 days. There is no refresh token — the client credentials grant doesn't use one. When a token expires, or whenever you'd rather not hold one for that long, call the token endpoint again with the same credentials and you get a fresh token.
A year is a deliberate choice. These are machine credentials with no user session behind them, and forcing an integration to re-authenticate every hour buys you nothing that rotating the secret doesn't buy you better.
Using Your Access Token
Send the token as a bearer token in the Authorization header:
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer {YOUR_ACCESS_TOKEN}',
}
That header works against the GraphQL API and the trigger endpoints alike — it's the same credential everywhere.
What Your Token Acts As
An OAuth App's token acts as the user who created the App. Everything that follows from that is worth understanding before you build on it:
- Your data stays yours. The token is scoped to the Paminga account of the creating user. It cannot read or write another account's data.
- Permissions apply. The token carries the creating user's permissions. If your organization has restricted that user through Permissions, the token is restricted the same way.
- The App outlives the person. If the creating user is later disabled or removed, the App keeps working — the integration belongs to your organization, not to whoever happened to click Create. Paminga continues the App under another active user in the same account, preferring an administrator.
- An App can't provision credentials. A token issued to an OAuth App cannot create, rotate, or delete OAuth Apps, for the reason given under Creating an App Through the API.
Listing Your Apps
The OAuth Apps grid lists only the Apps you created. Another user's Apps live under their own account, and secrets are never shown in a listing.
The same is true through the API:
query {
oauthApps(first: 25, page: 1, orderBy: [{ column: CREATED_AT, order: DESC }]) {
data {
client_id
name
description
created_at
updated_at
}
paginatorInfo {
total
currentPage
hasMorePages
}
}
}
Order by CLIENT_ID, NAME, DESCRIPTION, CREATED_AT, or UPDATED_AT. This is how you find the client_id to hand to the rotate and delete operations below.
Rotating a Client Secret
Rotation is what you do when a secret leaks, when someone with access to it leaves, or when your own policy says it's time.
Hover the Actions column for the App and click the rotate icon. Confirm, and Paminga issues a new secret and shows it in the same show-once dialog.
Rotating immediately invalidates the old client secret and revokes every access token already issued to that App. Any integration still using the old credentials stops working until you give it the new secret.
That's intentional. Client credentials tokens live for a year, so leaving already-issued tokens alive would make rotation a cosmetic remedy rather than a real one.
Through the API, which returns the new secret once and behaves identically:
mutation RotateSecret($id: ID!) {
rotateOauthAppSecret(id: $id) {
client_id
client_secret
}
}
The new secret is a credential, not a token — feed it back through the token exchange to get a working token again.
Deleting an OAuth App
Hover the Actions column and click the delete icon.
Deleting an App revokes it along with every access token issued to it. Any integration using those credentials stops authenticating right away, so make sure you know what's calling in before you delete.
Through the API:
mutation DeleteApp($id: ID!) {
deleteOauthApp(id: $id) {
client_id
name
}
}
Pass the App's client_id as $id. If the id doesn't match an App you own, deleteOauthApp returns null; rotateOauthAppSecret returns an OAuth App not found. error in the same situation.
Existing OAuth Apps
Paminga previously issued OAuth credentials through an older mechanism. Those credentials continue to work — nothing you have running today needs to change, and we have no plans to decommission them.
They no longer appear in the OAuth Apps grid, which now lists Apps created through the flow described on this page. When you next revisit an older integration, moving it onto a new OAuth App gets you rotation, revocation, and a credential you can see and manage.
Your ability to access account settings may depend on the permissions setup by your organization.


