API reference

Authentication, errors, limits and every partner action, written from Dium's source.

Last updated

How every call works

The Dium API is JSON over HTTPS. Each area has one PHP file under https://dium.io/api/. Every call is a POST with a JSON body, and the action field picks what happens. There is no versioned path and no SDK.

The shape of every call
curl -sS https://dium.io/api/ladder.php \
  -H "Content-Type: application/json" \
  -d '{"action":"get","slug":"acme-summit"}'

Browsers can call the API only from origins on Dium's CORS allowlist. Allowed methods are GET, POST and OPTIONS. Allowed headers are Content-Type, Authorization, X-Api-Key and X-Requested-With.

Authentication

There are two kinds of caller.

CallerHow it authenticatesUsed for
Your server (partner)X-Api-Key: <your key> header. The api_key body field still works but is legacy.Partner actions: tokens, Flows, Waves, Pages
A signed-in memberSession cookie, or Authorization: Bearer <token> from the mountEverything the Dium app does for that member

Scopes

Each partner key carries a list of scopes named after actions, such as auth.issue_token or exhibit.create. A key with * can call every partner action. Ask for the smallest set you need.

401 or 403

401 Unauthorized

No key was sent, or the key does not match any partner. Keys are compared in constant time.

403 Forbidden

The key is valid but its scopes do not include this action.

Partner keys are server-side secrets. Never send X-Api-Key from a browser, even though CORS allows the header. Anyone who can read your page source can read the key.

Responses and errors

Success returns HTTP 200 and a JSON object with "success": true plus the data for that action. Failures return an error status and an error message.

Success, from issue_token
{
  "success": true,
  "token": "<48 hex>",
  "expires_in": 300
}
Error
{
  "error": "..."
}
StatusMeaning
200The action ran.
400A required field is missing. Dium checks required fields before anything else.
401No valid partner key, or no signed-in member for a member action.
403The key lacks the scope, or the member lacks the role or profile-type permission.

Error messages are for people, not code: they are not a stable list of error codes yet. Branch on the HTTP status. The exact data fields returned by most actions are not published yet. Where a table on this page lists returned fields, they follow Dium's database schema.

Timestamps are stored in US Eastern time (UTC-4). Convert on your side before display.

Rate limits

Limits are counted per IP address, in one-minute windows.

ScopeLimit
Default for rate-limited endpoints60 requests per 60 seconds
answer.php create30 per minute
message.php send30 per minute
moderation.php report10 per minute
upload.php20 per minute

If you hit a limit, wait and retry with exponential backoff. Spread bulk jobs, such as seeding an agenda, over time rather than sending them in one burst.

Partner endpoints

These actions accept your partner key. Fields marked from schema are named after Dium's database columns or app code; confirm them with us before you depend on them.

POST/api/auth.php action: issue_token

Partner keyScope auth.issue_token

Mint a one-time sign-in token for a member. The token lasts 300 seconds and can be used once, at /home/autologin.php.

actionstringrequired

"issue_token"

emailstringrequired

The member's email. Must come from your own signed-in session.

namestringoptional

Display name, used when the account is new.

avatarstring (URL)optional

Avatar image URL, used when the account is new.

Request
curl -sS https://dium.io/api/auth.php \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $DIUM_API_KEY" \
  -d '{"action":"issue_token","email":"[email protected]","name":"Jane Doe"}'
Response shape
{
  "success": true,
  "token": "<48 hex characters>",
  "expires_in": 300
}

POST/api/ladder.php action: create

Partner keyScope ladder.create

Create a Flow (a community). Pass your own external_id: it is unique, so a retry cannot create a second Flow for the same event.

actionstringrequired

"create"

namestringrequired

Flow name shown to members.

slugstringoptional

URL slug, used in /asq/d/{slug}.

room_slugstringoptional

Groups sibling Flows into one Room that shares members and DMs.

external_idstring, max 64optional

Your ID for this Flow, such as an event ID. Unique.

settings_jsonobjectoptional

Flow settings: profile_types[], event_url, features and more.

Request
curl -sS https://dium.io/api/ladder.php \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $DIUM_API_KEY" \
  -d '{"action":"create","name":"Acme Summit 2026","slug":"acme-summit","external_id":"EVENT-123"}'
Response shape
{
  "success": true,
  ...
}

POST/api/ladder.php action: get

Public

Read one Flow with its settings. This action is public.

actionstringrequired

"get"

idintegeroptionalfrom schema

Flow ID. Send id or slug.

slugstringoptionalfrom schema

Flow slug.

Returned fields follow the Flow record: id, slug, room_slug, name, tagline, description, category, logo_url, banner_url, color_primary, color_accent, visibility, join_mode, external_id, settings_json.

Request
curl -sS https://dium.io/api/ladder.php \
  -H "Content-Type: application/json" \
  -d '{"action":"get","slug":"acme-summit"}'
Response shape
{
  "success": true,
  ...
}

POST/api/ladder.php action: update

Partner keyScope ladder.update

Change a Flow's name, description or settings.

actionstringrequired

"update"

idintegerrequiredfrom schema

Flow ID.

namestringoptional

New name.

descriptionstringoptional

New description.

settings_jsonobjectoptional

Replacement settings object.

Request
curl -sS https://dium.io/api/ladder.php \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $DIUM_API_KEY" \
  -d '{"action":"update","id":42,"description":"Questions and sessions for Acme Summit"}'
Response shape
{
  "success": true,
  ...
}

POST/api/ladder.php action: list

Partner keyScope ladder.list

List Flows, most recently active first.

actionstringrequired

"list"

Request
curl -sS https://dium.io/api/ladder.php \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $DIUM_API_KEY" \
  -d '{"action":"list"}'
Response shape
{
  "success": true,
  ...
}

POST/api/wave.php action: create

Partner keyScope wave.create

Create a Wave (a thread) in a Flow, for example one agenda session. Profile-type limits still apply to member-created Waves.

actionstringrequired

"create"

ladder_idintegerrequiredfrom schema

The Flow to post in.

titlestring, max 500required

Wave title.

wave_typestringoptional

One of conversation, question, broadcast, session, execution.

context_htmlstring (HTML)optional

Body text.

tagsarray of stringsoptional

Tags.

privacystringoptional

public, limited or invite.

scheduled_atdatetimeoptionalfrom schema

Start time for a session. Stored in US Eastern time (UTC-4).

duration_minintegeroptional

Session length in minutes.

meet_linkstring (URL)optional

Google Meet or Zoom link for a live session.

Request
curl -sS https://dium.io/api/wave.php \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $DIUM_API_KEY" \
  -d '{"action":"create","ladder_id":42,"wave_type":"session","title":"Keynote Q&A","scheduled_at":"2026-10-14 10:00:00","duration_min":45}'
Response shape
{
  "success": true,
  ...
}

POST/api/thread.php action: check_session

Public

Check whether a session thread already exists before you create one. Used by event partners during registration. thread.php also has create and update for session threads with a partner key.

actionstringrequired

"check_session"

The lookup fields for check_session are not published yet. Ask us for them during onboarding.
Request
curl -sS https://dium.io/api/thread.php \
  -H "Content-Type: application/json" \
  -d '{"action":"check_session"}'
Response shape
{
  "success": true,
  ...
}

POST/api/exhibit.php action: create

Partner keyScope exhibit.create

Create a Page (sponsor, exhibitor, speaker or partner). Safe to retry: pages are matched on Flow plus name, and on external_sponsor_id. Creating a Page also creates its discussion Wave.

actionstringrequired

"create"

ladder_idintegerrequiredfrom schema

The Flow the Page belongs to.

namestringrequired

Page name.

exhibit_typestringoptional

sponsor, exhibitor, speaker or partner.

taglinestringoptionalfrom schema

One line under the name.

websitestring (URL)optionalfrom schema

Website link.

about_htmlstring (HTML)optionalfrom schema

About section.

logo_urlstring (URL)optionalfrom schema

Logo image.

banner_urlstring (URL)optionalfrom schema

Banner image.

social_jsonarrayoptionalfrom schema

[{"platform","url","label"}]

team_jsonarrayoptionalfrom schema

[{"name","initials","role","status"}]

perks_jsonarrayoptionalfrom schema

[{"icon","title","desc"}]

cta_jsonobjectoptionalfrom schema

{"title","desc","button","url"}

external_sponsor_idstringoptionalfrom schema

Your ID for this sponsor. Used to avoid duplicates.

Request
curl -sS https://dium.io/api/exhibit.php \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $DIUM_API_KEY" \
  -d '{"action":"create","ladder_id":42,"name":"Northwind Labs","exhibit_type":"sponsor","external_sponsor_id":"SP-9"}'
Response shape
{
  "success": true,
  ...
}

Member session endpoints

These actions run as a signed-in member, with a cookie or a Bearer token. The Dium app calls them for you when you mount it. They are listed so you know what your mounted app does. They are not a stable public contract yet.

POST/api/auth.php action: validate

Member session

Return the signed-in member, or 401. Accepts a session cookie or Authorization: Bearer. Your mount calls this after autologin.

actionstringrequired

"validate"

Request
curl -sS https://dium.io/api/auth.php \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MEMBER_TOKEN" \
  -d '{"action":"validate"}'
Response shape
{
  "success": true,
  ...
}

POST/api/ladder.php action: join

Member session

Join a Flow as the signed-in member. Use join_as with a profile_type_slug to join with a specific profile type.

actionstringrequired

"join" or "join_as"

ladder_idintegerrequiredfrom schema

The Flow to join.

join_codestringoptionalfrom schema

Needed when the Flow's join mode is code.

profile_type_slugstringoptional

For join_as: the profile type code.

Request
curl -sS https://dium.io/api/ladder.php \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MEMBER_TOKEN" \
  -d '{"action":"join","ladder_id":42}'
Response shape
{
  "success": true,
  ...
}

POST/api/wave.php action: list

Member session

List Waves in a Flow. get reads one Wave by id.

actionstringrequired

"list" or "get"

ladder_idintegerrequiredfrom schema

For list: the Flow.

idintegeroptionalfrom schema

For get: the Wave ID.

Request
curl -sS https://dium.io/api/wave.php \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MEMBER_TOKEN" \
  -d '{"action":"list","ladder_id":42}'
Response shape
{
  "success": true,
  ...
}

POST/api/wave.php action: go_live

Member session

Start a live session: sets the Wave live and notifies members in real time. end_live stops it. Hosts and moderators only.

actionstringrequired

"go_live" or "end_live"

idintegerrequiredfrom schema

Session Wave ID.

meet_linkstring (URL)optional

Meeting link to open.

Request
curl -sS https://dium.io/api/wave.php \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MEMBER_TOKEN" \
  -d '{"action":"go_live","id":901,"meet_link":"https://meet.google.com/abc-defg-hij"}'
Response shape
{
  "success": true,
  ...
}

POST/api/exhibit.php action: get

Member session

Read one Page. list returns the Pages in a Flow.

actionstringrequired

"get" or "list"

idintegeroptionalfrom schema

For get: the Page ID.

ladder_idintegeroptionalfrom schema

For list: the Flow.

Request
curl -sS https://dium.io/api/exhibit.php \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MEMBER_TOKEN" \
  -d '{"action":"list","ladder_id":42}'
Response shape
{
  "success": true,
  ...
}

POST/api/message.php action: conversations

Member session

List the member's DM conversations, scoped to one Flow or Room.

actionstringrequired

"conversations"

room_slugstringoptionalfrom schema

Room scope.

ladder_idintegeroptionalfrom schema

Flow scope.

Request
curl -sS https://dium.io/api/message.php \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MEMBER_TOKEN" \
  -d '{"action":"conversations","room_slug":"acme-summit-2026"}'
Response shape
{
  "success": true,
  ...
}

POST/api/message.php action: send

Member session

Send a direct message. Limited to 30 per minute. Text is stored as plain text.

actionstringrequired

"send"

to_user_idintegerrequiredfrom schema

Recipient's user ID.

bodystringrequired

Message text.

parent_message_idintegeroptionalfrom schema

Reply inside a DM thread.

room_slugstringoptionalfrom schema

Room the conversation belongs to.

ladder_idintegeroptionalfrom schema

Flow context.

Request
curl -sS https://dium.io/api/message.php \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MEMBER_TOKEN" \
  -d '{"action":"send","to_user_id":17,"body":"See you at the keynote","room_slug":"acme-summit-2026"}'
Response shape
{
  "success": true,
  ...
}

Full action list

Every action the main API files accept. Most are used by the Dium app itself. If you need one that is not documented above, ask us before you build on it.

FileActions
auth.phplogin, validate, heartbeat, client_config, issue_token, verify_token, logout
ladder.phpcreate, update, get, list, members, join, join_as, pending_members, approve_member, reject_member, remove_member, pin_announcement, event_update, rsvp_join, sponsor_login, profile type actions
wave.phpcreate, update, get, list, delete, search, pin, archive, lock, go_live, end_live, join, follow, polls, breakouts, send_message, messages
answer.phpcreate (30 per minute), update, delete, list, best, helpful, like, react, reply_to, toggle_pin
exhibit.phpcreate, update, get, list, delete, wall chat actions, track_visit, track_event, analytics
message.phpconversations, messages, thread_messages, send, read, create_group, add_group_member, edit_message, delete_message, pin_message, unpin_message, react, unreact
thread.phpcheck_session (public), create, update