{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-apis/publicapi/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"type":"markdown"},"seo":{"title":"Authentication","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"authentication","__idx":0},"children":["Authentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The M2X Public API authenticates requests with a bearer token supplied in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}," header."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"obtaining-credentials","__idx":1},"children":["Obtaining credentials"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Contact your M2X account manager to provision API credentials for your integration — a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["client ID"]}," and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["client secret"]},". Store them securely — never commit them to source control or expose them in client-side code."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"requesting-a-token","__idx":2},"children":["Requesting a token"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The API uses the OAuth 2.0 ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["client credentials"]}," flow. Exchange your client ID and secret for a short-lived access token by sending a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}," to the token endpoint, then use that token to authorize your requests."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X POST \"$M2X_BASE_URL/openId/token\" \\\n  -H \"Content-Type: application/x-www-form-urlencoded\" \\\n  -d \"grant_type=client_credentials\" \\\n  -d \"client_id=$M2X_CLIENT_ID\" \\\n  -d \"client_secret=$M2X_CLIENT_SECRET\" \\\n  -d \"scope=read:products\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["List the scopes your integration needs in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["scope"]}," parameter, separated by spaces — see ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"#scopes"},"children":["Scopes"]}," for how to choose them. The full set of available scopes is listed in the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Authorize"]}," dialog in the API reference."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A successful response returns the access token along with its type and lifetime:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"access_token\": \"<your-access-token>\",\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 600 // how long the token is valid, in seconds\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Tokens expire"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Access tokens are short-lived. Request a new one when the current token nears the end of its lifetime, or whenever a request comes back ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"authorizing-a-request","__idx":3},"children":["Authorizing a request"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Include your token as a bearer token on every request:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl \"$M2X_BASE_URL/apis/v0/products\" \\\n  -H \"Authorization: Bearer $M2X_TOKEN\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"scopes","__idx":4},"children":["Scopes"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each token carries a set of ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["scopes"]}," that determine which operations it can perform. When you request a token, you specify which scopes it should include — request only the scopes your integration actually needs."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This follows the principle of least privilege — for example, requesting only read scopes produces a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["read-only"]}," token that can fetch data but can't create, update, or delete anything. A request that needs a scope the token doesn't hold is rejected with a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403 Forbidden"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The reference docs are an exception: when you request a token through ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"/apis/publicapi/guides/try-it#token-scopes"},"children":["Using \"Try it\""]},", all scopes are enabled by default and you can toggle off the ones you don't want."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"handling-auth-errors","__idx":5},"children":["Handling auth errors"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Status"},"children":["Status"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Meaning"},"children":["Meaning"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"What to do"},"children":["What to do"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Missing or invalid token"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Check the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}," header and token validity."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403 Forbidden"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Token lacks permission"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Confirm the token's scope with your M2x account manager."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"next-steps","__idx":6},"children":["Next steps"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Return to ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"/apis/publicapi/guides/getting-started"},"children":["Getting started"]}," to make your first call."]}]}]},"headings":[{"value":"Authentication","id":"authentication","depth":1},{"value":"Obtaining credentials","id":"obtaining-credentials","depth":2},{"value":"Requesting a token","id":"requesting-a-token","depth":2},{"value":"Authorizing a request","id":"authorizing-a-request","depth":2},{"value":"Scopes","id":"scopes","depth":2},{"value":"Handling auth errors","id":"handling-auth-errors","depth":2},{"value":"Next steps","id":"next-steps","depth":2}],"frontmatter":{"seo":{"title":"Authentication"}},"lastModified":"2026-06-10T00:28:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/apis/publicapi/guides/authentication","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}