Developer docs
API reference

Organisation API

Partner JWT API for servers you control. Create classes, curriculum, join codes, grade work, manage communities, and call TribeMate. Base path: https://www.tribepeer.com/api/partner/v1.

Exchange tp_id_ + tp_sec_ for a Bearer token. Live keys return 402 until Live / Widget Pro / Campus is granted. Scopes on the token gate each route. Full AI docs: AI · TribeMate.

Authentication

POST /partner/v1/auth/token

Public. Returns a partner JWT (~1 hour). Call only from a server.

Request body

client_idstring, requiredtp_id_…
client_secretstring, requiredtp_sec_… — never ship to browsers
POST /api/partner/v1/auth/token
curl -s https://www.tribepeer.com/api/partner/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "tp_id_…",
    "client_secret": "tp_sec_…"
  }'

Success 200

application/json
{
  "access_token": "eyJ…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "expires_at": "2026-09-06T12:00:00+00:00",
  "scopes": ["tribes:read", "tribes:write", "ai:chat", "…"]
}

Errors

401Invalid client credentials
403Key deactivated or institution inactive
402Live key without a paying plan

Institution profile & branding

GET /partner/v1/me

Who this key belongs to, branding, key state, and scopes.

Header: Authorization: Bearer <token>

Response 200

application/json
{
  "institution": {
    "uuid": "…",
    "name": "Lagos High School",
    "organization_type": "school",
    "status": "active",
    "owner": { "name": "…", "email": "…", "username": "…" }
  },
  "branding": {
    "display_name": "Lagos High",
    "logo_url": "https://…",
    "accent_hex": "#9A3412",
    "welcome_markdown": "…"
  },
  "api_key": {
    "id": 12,
    "name": "Production",
    "client_id": "tp_id_…",
    "is_active": true,
    "state": "live"
  },
  "scopes": ["tribes:read", "tribes:write", "…"]
}
PATCH /partner/v1/me/branding

Update Campus / widget brand. Partial updates allowed.

Request body

display_namestring ≤160optional
logo_urlstring ≤500optional (pass null to clear)
accent_hex#RGB / #RRGGBBoptional; # added if missing
welcome_markdownstring ≤8000optional

Response 200

application/json
{ "branding": { "display_name": "Lagos High", "logo_url": null, "accent_hex": "#9A3412", "welcome_markdown": null } }

Tribes (classes)

GET /tribestribes:readList classes for this institution
POST /tribestribes:writeCreate a class
GET /tribes/{uuid}tribes:readShow one class
PATCH /tribes/{uuid}tribes:writeUpdate metadata
POST /tribes/{uuid}/publishtribes:writePublish
POST /tribes/{uuid}/archivetribes:writeArchive
DEL /tribes/{uuid}tribes:writeDelete
POST /partner/v1/tribes
Scope: tribes:write

Create a class owned by the institution owner.

Request body

titlestring ≤120, required
categoryrequired · TribeCategory value (e.g. science, technology)
aboutstring ≤2000, optional
tagsarray|string, optional
visibilitypublic | private_listed | hidden (default hidden)
access_typefree | paid | tpt
price_kobointeger ≥0 when paid
tpt_costinteger ≥0 when tpt
publishboolean — publish immediately
POST /api/partner/v1/tribes
curl -s https://www.tribepeer.com/api/partner/v1/tribes \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "SS1 Biology",
    "category": "science",
    "about": "Term 1 cohort",
    "visibility": "hidden",
    "access_type": "free",
    "publish": true
  }'

Tribe members

GET /tribes/{uuid}/membersmembers:read
POST /tribes/{uuid}/membersmembers:write · body: user lookup fields
PATCH /tribes/{uuid}/membersmembers:write · role / active
DEL /tribes/{uuid}/membersmembers:write
GET /tribes/{uuid}/invitationsmembers:read

Announcements

GET /tribes/{uuid}/announcementsannouncements:read
POST /tribes/{uuid}/announcementsannouncements:write
GET/tribes/{uuid}/announcements/{announcementUuid}
PATCH / DELupdate / delete announcement
POST …/publish · …/pinpublish or pin

Modules & materials

GET /tribes/{uuid}/modulesmaterials:read
POST /tribes/{uuid}/modulesbody: title, optional description
PATCH / DEL /modules/{moduleUuid}materials:write
GET /tribes/{uuid}/materialsquery: type, module_uuid
POST /tribes/{uuid}/materialscreate text / quiz / assignment
GET / PATCH / DEL/materials/{materialUuid}
POST …/materials/{materialUuid}/publishpublish lesson
POST /partner/v1/tribes/{uuid}/materials
Scope: materials:write

Create a lesson, quiz, or assignment under a module.

Common fields

module_uuiduuid, required (or module_id)
typetext | quiz | assignment
titlestring ≤255, required
descriptionoptional
contentlesson body (text) or unused when quiz uses questions
is_publishedboolean
requires_prevboolean — gate behind previous material
pass_score1–100 (quiz)
max_attemptsinteger ≥1 (quiz)
timing_mode / time_limit_secondsquiz timing
questionsarray of quiz questions (serialized into content)
deadline_atrequired for new assignments
submission_modefile | text | both (assignments)
instructionsassignment brief

Example quiz body

JSON
{
  "module_uuid": "…",
  "type": "quiz",
  "title": "Leaf structure check",
  "pass_score": 70,
  "max_attempts": 2,
  "is_published": true,
  "questions": [
    {
      "prompt": "Where does photosynthesis mainly occur?",
      "type": "mcq",
      "options": ["Root", "Leaf", "Stem"],
      "answer": "Leaf"
    }
  ]
}

Response 201

{ "material": { "uuid", "module_uuid", "type", "title", "is_published", "questions"| "content", … } }

Submissions & grading

GET /tribes/{uuid}/submissionssubmissions:read · quiz + assignment rows
POST /tribes/{uuid}/submissions/assignments/{submissionUuid}/gradesubmissions:write

Grade body typically includes score / feedback fields accepted by the grading controller. Prefer the Learner manage routes if staff work inside Campus UI.

Join codes & enrollments

GET /join-codesjoin_codes:write
POST /join-codesbody: tribe_uuid, optional label, max_uses, expires_at
POST /join-codes/{code}/revokerevoke
POST /enrollmentsenrollments:write · place a learner by email / user id into a tribe

Students & results

GET /studentsstudents:read · query filters as validated by controller
GET /resultsresults:read · scores across your tribes

Communities & chat

Institution-owned communities, members, join requests, threads, and messages.

GET / POST /communitieslist / create
GET / PATCH / DEL /communities/{uuid}CRUD
/communities/{uuid}/membersGET/POST/PATCH/DELETE · scopes communities:read / community_members:write
/invitations, /join-requests, approve/rejectmembership workflow
/threads, /threads/{threadUuid}/messagesclassroom chat · community_messages:write to post
pin / lock / read / message PATCH|DELETEmoderation

AI

POST /ai/chat and GET /ai/usage (scope ai:chat). Full request / response / multi-language samples: AI · TribeMate reference.

Common errors

401Missing or expired partner JWT
403Scope missing on token
402Plan / AI entitlement / quota
404Tribe / material not in this institution
422Validation
429Throttle

Learner API → AI docs