Getting Started: Your First Organization and User
This tutorial will guide you through the basic setup of creating an organization, adding a user, and authenticating to get an API token.
Prerequisites
- You need a tool for making API requests, like
curlor Postman. - You should have the base URL of the ButtrBase API endpoint. For this tutorial, we'll assume it's
https://api.buttrbase.com.
---
Step 1: Create a New Organization
First, you need an organization to house your users and applications.
Endpoint: POST /api/organizations
Send a POST request with the name of your new organization. The appid will determine which ButtrBase application this organization belongs to.
Example Request using curl:
curl -X POST https://api.buttrbase.com/api/organizations -H "Content-Type: application/json" -d '{ "name": "my-awesome-app", "org_display_name": "My Awesome App", "appid": 50 }'
Expected Response (201 Created):
{
"data": {
"id": 1,
"name": "my-awesome-app",
"org_uuid": "org-uuid-12345"
}
}
You have now created your first organization! Make sure to take note of the org_uuid.
---
Step 2: Create a New User
Now, let's create a user. As of June 2026 the new flow is split across three endpoints so that the user explicitly picks their org instead of the old API auto-creating one named after their email's domain.
#### 2a. Send a one-time code
Endpoint: POST /api/auth/otp
curl -X POST https://api.buttrbase.com/api/auth/otp -H "Content-Type: application/json" -d '{ "email": "test.user@example.com", "app_uuid": "", "org_uuid": "ae12ac1d-45c9-4eb7-8ddc-4c50d257b954", "app_name": "buttrbase" }'
#### 2b. Verify the code → exchange for a signup token
Endpoint: POST /api/auth/otp/verify
curl -X POST https://api.buttrbase.com/api/auth/otp/verify -H "Content-Type: application/json" -d '{ "email": "test.user@example.com", "otp": "123456", "app_uuid": "" }'
Response includes a short-lived token — that's the signup_token the next step needs.
#### 2c. Finalize the registration with an org choice
Endpoint: POST /api/auth/finalize-registration
Pick exactly one of two paths via org_choice:
(a) Create a brand-new org:
curl -X POST https://api.buttrbase.com/api/auth/finalize-registration \
-H "Content-Type: application/json" \
-d '{
"email": "test.user@example.com",
"password": "",
"first_name": "Test",
"last_name": "User",
"app_uuid": "",
"signup_token": "",
"org_choice": { "type": "create", "name": "Acme Inc" }
}'
(b) Accept an existing org's invitation:
curl -X POST https://api.buttrbase.com/api/auth/finalize-registration \
-H "Content-Type: application/json" \
-d '{
"email": "test.user@example.com",
"password": "",
"first_name": "Test",
"last_name": "User",
"app_uuid": "",
"signup_token": "",
"org_choice": { "type": "accept_invite", "invitation_token": "" }
}'
Response (200):
{
"data": {
"message": "User registered successfully",
"user_uuid": "user-uuid-abcde",
"access_token": "eyJhbGciOiJIUzI1NiI...",
"refresh_token": "eyJhbGciOiJIUzI1NiI...",
"token_type": "Bearer",
"expires_in": 420
}
}
#### Helper: live name-availability check
While the user types an org name in your UI, debounce a call to:
GET /api/auth/check-org-name?name=Acme%20Inc
Returns { available, reason, normalized }. Reason is one of empty | too_short | too_long | invalid_chars | taken.
Great! You now have a user + an org in your application.
---
Step 3: Authenticate as the User
The final step is to log in as the new user to get a JWT access token.
Endpoint: POST /api/auth/login
Example Request using curl:
curl -X POST https://api.buttrbase.com/api/auth/login -H "Content-Type: application/json" -d '{ "email": "test.user@example.com", "password": "a-very-secure-password", "org_name": "my-awesome-app" }'
---
Framework-Specific SDKs
For the best developer experience, we provide native wrappers for all major frontend frameworks. These are thin, zero-cost layers on top of the core JS SDK.
| Framework | Package | Key Features |
| :--- | :--- | :--- |
| React | @buttrbase/react-sdk | useButtrBasePosts, |
| SolidJS | @buttrbase/solid-sdk | createButtrBasePosts, |
| Vue | @buttrbase/vue-sdk | useButtrBasePosts, ButtrBaseImage (component) |
| Angular | @buttrbase/angular-sdk | ButtrBaseService, |
| Svelte | @buttrbase/svelte-sdk | createButtrBaseStore, optimized stores |
| Next.js | @buttrbase/nextjs | getButtrBasePosts, RSC fetchers, next/image custom loader |
| Remix | @buttrbase/remix | fetchButtrBasePosts, native route loaders |
| Astro | @buttrbase/astro | buttrbaseImageService (Zero-JS build-time optimization) |
Third-Party Integrations
WordPress Plugin (buttrbase-wp-plugin)
If your marketing site currently runs on WordPress, you don't need to rebuild it from scratch to get our Edge CDN benefits.Simply upload the ButtrBase Edge CDN & Media Optimizer plugin (found in the sdks/wordpress-plugin directory). Once activated, it intercepts all media library calls and automatically offloads your local .jpg and .png files to cdn.buttrbase.com, instantly serving sub-millisecond WebP/AVIF variants to your visitors without paying for tools like Smush or WP Offload Media.
Using the ButtrBase JS SDK
While curl is great for testing, our JS SDK provides a type-safe and more convenient way to interact with the API.
Installation
npm install @buttrbase/js-sdk
Basic Usage
import { ButtrBaseClient } from '@buttrbase/js-sdk';const client = new ButtrBaseClient('https://api.buttrbase.com');
async function setup() {
// Login
const auth = await client.auth.login(
'test.user@example.com',
'a-very-secure-password',
'my-awesome-app'
);
console.log('Logged in! Token:', auth.access_token);
// Create an organization (v2 endpoint via SDK)
const org = await client.organizations.create('new-org', 'New Org Display Name');
console.log('Created org:', org.org_uuid);
}
Using the ButtrBase Next.js SDK
If you are using Next.js App Router, do not use the React hooks for fetching data, as that forces your components to render on the client, destroying SEO.
Instead, use the @buttrbase/nextjs package which provides native Server Component fetchers that automatically integrate with the Next.js Data Cache.
1. Server-Side Data Fetching
// app/blog/page.tsx
import { getButtrBasePosts } from '@buttrbase/nextjs';export default async function BlogPage() {
// This executes at build time or revalidates automatically via Next.js ISR
const posts = await getButtrBasePosts('https://api.yourdomain.com', { revalidate: 3600 });
return (
{posts.map(post => {post.title}
)}
);
}
2. Next.js Image Optimization
To take advantage of our Global Asset CDN without paying Vercel for image optimization, use our custom loader for the next/image component.
In your next.config.js:
module.exports = {
images: {
loader: 'custom',
loaderFile: './node_modules/@buttrbase/nextjs/dist/image-loader.js',
},
}
Now, whenever you use , Next.js will automatically route the resizing through cdn.buttrbase.com.
Experimental Version Switching (Binary/FlatBuffers)
To test higher performance binary transport (FlatBuffers) available in the v2.x series, you can switch the SDK version dynamically.
// Switch to v2 binary mode
client.setVersion('2.0.0-binary');// Subsequent calls will now negotiate FlatBuffers automatically
const users = await client.organizations.listUsers('org-uuid-12345');
---
Version Switching Widget
If you are using our pre-built Admin UI or embedding our widgets, you can use the Runtime Version Toggle to switch between stable (JSON) and experimental (Binary) flows.
1. Open the Connection Panel (bottom left of the dashboard).
2. Look for the SDK Version dropdown.
3. Select 2.0.0-experimental-binary to enable zero-copy binary transport.
4. Observe the Network tab in your browser to see application/x-flatbuffers in the Accept and Content-Type headers.
---
Connecting AI Agents (MCP Server)
ButtrBase provides an official Model Context Protocol (MCP) server so your AI assistants (like Claude Desktop or Cursor) can interact directly with your organizations, users, and billing data.
Running the MCP Server
You can run the MCP server directly using npx or by building it from source. Provide your Service Account token via the environment:
export BUTTRBASE_SVC_TOKEN="bb_svc_your_agent_key"
npx -y @buttrbase/mcp-server
Configuring Claude Desktop
To connect Claude Desktop to your ButtrBase platform, edit your claude_desktop_config.json:
{
"mcpServers": {
"buttrbase": {
"command": "npx",
"args": ["-y", "@buttrbase/mcp-server"],
"env": {
"BUTTRBASE_API_URL": "https://api.buttrbase.com",
"BUTTRBASE_SVC_TOKEN": "bb_svc_your_agent_key"
}
}
}
}
Once connected, you can ask Claude questions like: *"Show me the recent audit logs for Acme Corp." *"Record 5000 Claude 3 Opus tokens to org-uuid-123." *"List all users in the engineering organization."
---
Expected Response for Login (200 OK):
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI...",
"user": {
"id": 1,
"user_uuid": "user-uuid-abcde",
"email": "test.user@example.com",
"org_uuid": "org-uuid-12345"
}
}
You now have an access token and the user's UUID! You can use this token in the Authorization header of subsequent requests to access protected endpoints.
---
Step 4: Supercharge your Marketing Site
To fulfill our mission of "Everything for the SaaS except the SaaS", you can immediately use your new Org's UUID to serve hyper-optimized media on your public marketing pages via our Global Edge CDN.
Responsive Logo:
Dynamic Social Card: