oauth.scopes and returns to the first URL in oauth.redirect_urls.https://app.example.com/numu/callback?code=numu_code_ā¦&store_id=3fa85f64-5717-4562-b3fc-2c963f66afa6&state=ā¦×tamp=1767225600&hmac=6f3cā¦c81| Parameter | Is |
|---|---|
code | Single use, valid for 10 minutes |
store_id | The store that installed your app |
state | The value from the consent link |
timestamp | Unix seconds, when NUMU signed the redirect |
hmac | The signature over the other parameters |
?error=access_denied&state=ā¦, with no code and no signature.hmac and reject a timestamp older than 5 minutes, before anything else.state protects the flows you start yourself: when you sent the merchant to the consent screen (Ask for more scopes), check that state is the value you sent. When the merchant started from the App Store, NUMU chose state, and the hmac is what proves the redirect is genuine.{
"success": true,
"data": {
"access_token": "numu_app_ā¦",
"scopes": ["orders:read", "orders:write"],
"store_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
}store_id. Then send the merchant to a page of your app, in Arabic unless they chose English.hmac, URL-decoded.name=value, separated by &.hmac in constant time, and reject a timestamp older than 5 minutes.code=numu_code_ā¦&state=ā¦&store_id=3fa85f64-ā¦×tamp=1767225600.t= prefix and no body. Two rules keep the signed string predictable:state from letters, digits, - and _ only.app_url no query string of its own. NUMU signs only the parameters it adds.{"success": false, "error": {"code": "HTTP_ERROR", "message": "invalid client credentials"}}.| Status | error.message | What to do |
|---|---|---|
401 | invalid client credentials | Check client_id and client_secret. After a rotation, only the new secret works |
400 | invalid, expired or already used code | A code works once and for 10 minutes. Send the merchant through the consent screen again |
400 | grant_type must be authorization_code | Leave out grant_type, or send authorization_code |
https://numueg.app/api/v1/stores/{store_id}/ā¦. A token works only on its own store; any other store_id answers 403.GET /auth/api-key/me tells you what a token is: app_slug, store_id, store_name, subdomain, currency, default_language and scopes. Call it at startup.Idempotency-Key on writes, errors.401 and Invalid or revoked app token, when:401 on one store as an uninstall of that store: stop its jobs and stop calling the API for it.https://merchant.numueg.app/oauth/authorize?client_id=ā¦&store_id=ā¦&redirect_uri=https%3A%2F%2Fapp.example.com%2Fnumu%2Fcallback&scope=orders%3Aread%20orders%3Awrite%20catalog%3Aread&state=ā¦scope: space-separated. It must include every scope in oauth.scopes, and may add any from oauth.optional_scopes.redirect_uri: one of your redirect_urls, byte for byte.state: required. Make a new one for each request, and check it when the merchant returns.store_id: the store. The merchant must be signed in to NUMU as its owner.https://merchant.numueg.app/oauth/authorize?client_id=numu_ci_ā¦&store_id=<development store id>&redirect_uri=<one of your redirect_urls, URL-encoded>&scope=<your scopes, space-separated>&state=<random>app_url with signed parameters:https://app.example.com/numu?store_id=3fa85f64-5717-4562-b3fc-2c963f66afa6&locale=ar×tamp=1767225600&hmac=ā¦store_id, then start your own session. Show the page in Arabic when locale=ar./oauth/token and /oauth/revoke.200, with data.revoked set to true, even for a token it does not know. So it cannot be used to test whether a token is valid.