Overview
Getting Started
Integration Guide
Widgets
Security & Access
Webhooks
Powered by DocStar
  1. Guides
  2. Integration Guide

Integration Guide

This guide takes a developer, or an AI coding agent working in a developer's codebase, from nothing to a working 36Blocks integration. Read it first, then follow the links for detail.

Widgets are the entry point. You integrate 36Blocks by embedding its widgets (login, profile, member management, organization settings) and handling one redirect. Reach for a widget before building any auth or account UI yourself. See Widgets.

36Blocks fully manages end-user accounts server-side. Your app does not need its own users table or any auth-related database schema. You add a frontend widget, handle one redirect, store a session token, and call a few backend APIs.

Base URL for all APIs: https://routes.msg91.com/api

#

Concepts

Term Meaning
Client A 36Blocks account holder: the platform owner integrating 36Blocks.
Block A container owned by a client. Each Block has its own themes, user-management settings, roles and permissions, and redirect URL. A client can own several Blocks.
reference_id The unique id of a Block, created in the 36Blocks dashboard. Needed by the Authentication widget.
authkey A backend credential provided by 36Blocks to the account owner. Used only by the Server-to-Server (Auth Key) calls. No API returns it.
c_user An end user of your app. Each c_user belongs to exactly one Block.
c_company A tenant or organization inside a Block. A c_user can belong to several c_companies, with a different role and permissions in each.
proxy_auth_token The session token 36Blocks issues after a c_user signs in. Sent in the proxy_auth_token header on signed-in API calls. It expires when the Block's Session Time elapses or when the user logs out.
Redirect URL Set per Block. After sign-in, 36Blocks redirects the browser here with proxy_auth_token in the query string.
#

The flow

#

1. Set up the Block (dashboard, done by a person)

Create a Block in the 36Blocks dashboard. It gives you a reference_id. Set the Block's redirect URL, login methods, branding and roles. This happens in the dashboard, not in your code. See Getting Started.

If you are an AI agent, ask the user for the reference_id and confirm the redirect URL is set. Do not invent either.

The widget flow below needs only the reference_id. Backend calls that run without a signed-in user (Server-to-Server (Auth Key)) also need an authkey. 36Blocks provides it to the account owner. No endpoint or widget returns it, so it cannot be fetched from code, and an agent gets it from the user.

#

2. Add the login page

Add the Authentication widget (type: 'authorization') with the Block's reference_id. See Widgets for the snippet.

#

3. Handle the redirect

After sign-in, 36Blocks redirects the browser to the Block's redirect URL. Your app needs a route at that URL that reads the query string:

  • Check error first. On failure the redirect carries error (and usually error_description) instead of a token.

  • Otherwise read proxy_auth_token and refresh_token. state, expire_at, user_ref_id, company_ref_id and is_new_user are also included. See Redirect Parameters.

#

4. Store the session

Store the token on your backend side (see Token storage below) so later requests from that browser are authenticated.

#

5. Fetch the user

Call Get Details with the session token to get the user's profile, all their companies, and their current company with role and permissions:

curl --request GET \
  --url https://routes.msg91.com/api/c/getDetails \
  --header 'Content-Type: application/json' \
  --header 'proxy_auth_token: {{proxy_auth_token}}'
{
  "data": [
    {
      "id": 99152,
      "name": "...",
      "email": "...",
      "client_id": 8,
      "c_companies": [
        { "id": 61434, "name": "...", "role_id": 1, "role_name": "Owner" }
      ],
      "currentCompany": {
        "id": 63363,
        "role": { "id": 1, "name": "Owner", "is_default": true },
        "permissions": ["create_c_company", "update_c_company"]
      }
    }
  ],
  "status": "success",
  "hasError": false,
  "errors": []
}

Use it to render user-specific views, to gate features on currentCompany.permissions, and to know which company is active. The token itself carries no data. See Session & Authorization for the alternative JWT model.

#

6. Add user-facing features

Pick the widgets that fit what you are building. See "Which widget for which page" in Widgets:

You are building Widget (type)
Login or sign-up authorization
Team management: invite teammates, change roles, remove users user-management
Account settings or "my profile" user-profile
Organization or workspace settings organization-details
#

7. Keep the session alive

Sessions end after the Block's Session Time. When a signed-in call returns 401, exchange the stored refresh_token with the Refresh Session Token endpoint (POST /c/refreshToken). Refresh tokens rotate, so always save the new one. Send the user to the login page only if the refresh fails. See Refresh Tokens.

#

8. Log out

Call Log Out (DELETE /c/logout) with the proxy_auth_token header, then clear the stored session or cookie. It also revokes the user's refresh tokens.

curl --request DELETE \
  --url https://routes.msg91.com/api/c/logout \
  --header 'proxy_auth_token: {{proxy_auth_token}}'
#

9. Support multiple companies (if users can belong to more than one)

Where your app lets a user switch organization, such as an org switcher in the nav, call Switch Company:

curl --request POST \
  --url https://routes.msg91.com/api/c/switchCompany \
  --header 'Content-Type: application/json' \
  --header 'proxy_auth_token: {{proxy_auth_token}}' \
  --data '{ "company_ref_id": 61434 }'

The same proxy_auth_token stays valid. The response includes a jwt reflecting the new current company and permissions. Treat it as a refreshed session for that company.

#

Token storage

  • Default: an HTTP-only, Secure, SameSite=Lax (or Strict) cookie, set by your own backend after it receives the token from the redirect. This keeps the token out of reach of client-side JavaScript, which limits token theft through XSS, and the browser still sends it to your backend automatically.

  • Your backend reads the cookie on each request and forwards it as the proxy_auth_token header when calling 36Blocks APIs.

  • On logout, call DELETE /c/logout, then clear the cookie.

  • For a stateless or mobile client with no cookies, such as a native app or a single-page app calling a separate API server, use secure device storage (Keychain or Keystore) or hold the token in memory. Be aware these expose the token more than an HTTP-only cookie does.

  • Do not use localStorage or sessionStorage unless cookies genuinely cannot work for your setup, and then accept the XSS tradeoff.

#

Adapting the widgets to your framework

The widgets are plain <div> and <script> snippets. A client-side widget needs a mount point and a configuration object. Adapt the mounting to the framework, and read authToken and route parameters the way the rest of the app does.

  • Plain HTML and JavaScript: use the snippet as it is.

  • React: wrap it in a component that injects the script on mount (for example in useEffect, appending the script tag next to a ref'd container) and removes it on unmount.

  • Vue: the same idea with onMounted and onUnmounted.

  • Next.js and other server-rendered frameworks: the widget script must run in the browser, so use a client component ('use client' in the App Router, or a dynamic import with ssr: false). Handle the redirect URL as a server route that reads proxy_auth_token from the query string and sets the cookie.

  • Other frameworks: apply the same principle and use the framework's own routing for the redirect.

#

One Block or several

A client can own several Blocks. Create a new Block for:

  • Separate environments. Use separate Blocks for staging and production so test users never mix with real customers.

  • Separate products. If you run more than one distinct product with its own user base, each usually gets its own Block, because each c_user belongs to exactly one Block.

  • Different auth or branding configuration. A Block's theme, redirect URL and settings are Block-wide. If two surfaces need materially different configuration, use separate Blocks.

Reuse the same Block when it is the same user base and the same app deployed to different pages or subdomains. Configure one redirect URL that all those surfaces use, and branch inside your app after login.

#

Rules for AI coding agents

  • Signed-in calls authenticate with the proxy_auth_token header. Do not use Authorization: Bearer.

  • Server-to-server calls use the authkey header. It is a backend secret: never put it in browser or mobile code, and never commit it. 36Blocks provides it to the account owner and no API returns it, so it comes from the user.

  • Always check hasError in the response body. Some business errors return HTTP 200, and authentication or permission failures usually return 401 rather than 403.

  • Gate features on the permissions returned by Get Details, and tell the user which permission is missing when a call returns 401.

  • Do not create a users table or password handling. 36Blocks owns that.

  • Ask a person for dashboard-only steps (creating the Block, redirect URL, roles) and for the reference_id. Never invent ids, tokens or emails.

  • The full endpoint reference is in the modules of this documentation: Sessions, Companies & Users, API Keys Roles & Permissions, Blocks, Server-to-Server (Auth Key), OAuth 2.0, Analytics and Billing.

Getting Started

Create and configure a Block in the dashboard.

Widgets

Snippets for all four widgets.

Session & Authorization

Token-only or JWT sessions.

On this page

  • Concepts
  • The flow
  • Set up the Block (dashboard, done by a person)
  • Add the login page
  • Handle the redirect
  • Store the session
  • Fetch the user
  • Add user-facing features
  • Keep the session alive
  • Log out
  • Support multiple companies (if users can belong to more than one)
  • Token storage
  • Adapting the widgets to your framework
  • One Block or several
  • Rules for AI coding agents
336Blocks User API · API documentation

Build with 36Blocks User. Let AI do the rest.

Copy the instructions, paste them into your AI, and tell it what you want to build.

Paste into your AI and tell it what you want to build.

·
Published with DocStar