Skip to Content
Go API referenceSchemas & error contracts

Schemas & error contracts

Use this page together with the Executable contract cookbook. The cookbook identifies every operation; this registry gives the stable JSON and multipart shapes that a UI, agent, or generated client needs to encode and decode. Fields marked write are accepted from a caller. Fields marked read are produced by the service and must not be treated as writable simply because they appear in a response.

HTTP conventions

ConcernGo APIAI indexerAgent gateway
Base path/api/v1// and /v1/index//health, /v1/proxy, /mcp
Auth headerAuthorization: Bearer <access JWT> on protected routesAuthorization: Bearer <SERVICE_TOKEN> when configuredOptional gateway token on /v1/proxy; each protected downstream call also carries a user JWT in user_token
JSON content typeapplication/json for JSON writesapplication/json for writesapplication/json for /v1/proxy
MultipartUpload file/class_obj; profile profile_image or imageNeverupload_file converts base64 to multipart internally
Trailing slashRequiredNot used by the FastAPI paths shown hereDownstream Go path retains its slash

Shared response shapes

Go API envelope

Most Go resource operations return the following envelope. Check both the HTTP status and success: readiness can be 503 with a diagnostic object even where the envelope shape is still present.

{ "success": true, "message": "Class created successfully", "data": {}, "errors": null }
FieldTypeMeaning
successbooleanApplication-level result.
messagestringHuman-readable operation result. Do not use as a machine identifier.
dataobject, array, page, or nullSuccessful payload; selected error handlers also place a detail object here.
errorsnull, object, or validation collectionStructured validation or domain error data when supplied by the handler.

Pagination

Class, upload, share, friendship, marketplace, library, notification, and similar list handlers use a page object. Send page and page_size where an endpoint advertises pagination; handlers default to page 1 and typically cap page size at 100.

{ "count": 42, "next": "/api/v1/uploads/?page=2&page_size=20", "previous": "", "results": [] }

Go error envelope

{ "success": false, "message": "Invalid input", "data": null, "errors": { "detail": "reason when the handler supplies one" } }

The token refresh endpoint is intentionally different. Its invalid-token responses are a direct detail object:

{"detail":"Token is invalid or expired"}

FastAPI error body

The AI indexer and FastMCP gateway use FastAPI exceptions for transport and validation errors:

{"detail":"Invalid service token"}

Authentication schemas

RegistrationRequest — POST /auth/register/

{ "email": "learner@example.com", "full_name": "Asha Mrema", "user_type": "student", "password": "SecurePass9", "confirm_password": "SecurePass9" }
FieldTypeRequiredConstraints
emailstringYesTrimmed and lowercased by the handler.
full_namestringYesTrimmed; cannot be blank.
user_typestudent or lecturerNoDefaults to student.
passwordstringYesAt least 8 characters and not entirely numeric.
confirm_passwordstringYesMust match password.

LoginResponse

{ "success": true, "message": "Login successful", "data": { "user": { "id": 42, "email": "learner@example.com", "username": "Asha Mrema", "user_type": "student", "is_approved": true, "university": "Kibegi University", "phone_number": "+255712345678", "phone_verified": true, "profile_image": null, "profile_image_url": null, "date_joined": "2026-08-21T09:00:00Z" }, "tokens": {"refresh":"<JWT>","access":"<JWT>"} }, "errors": null }

Authentication error matrix

OperationHTTP statusMachine-relevant response condition
Register400Invalid registration details, duplicate email, or password violation.
Login401message is Invalid email or password.
Login403Lecturer is pending approval.
Login or token issue503Authentication dependency is unavailable.
Refresh400Direct { "detail": "refresh is required" }.
Refresh401Direct { "detail": "Token is invalid or expired" }.
Profile / password / phone401Missing or invalid access JWT.
Profile update400Blank username or malformed JSON.
Phone OTP send400Invalid or duplicate Tanzania number.
Phone OTP send429More than three recent OTP requests for the same number.
Phone OTP verify400Missing, expired, incorrect, or exhausted OTP.

Core resource schemas

ClassWrite — POST /classes/ and PUT/PATCH /classes/{class_uuid}/

{ "name": "Distributed Systems", "description": "Term 1 class space", "is_public": false }

name is mandatory at creation. On update, each field is optional; the authenticated class creator is the only permitted writer.

ClassRead

{ "id": "11111111-2222-3333-4444-555555555555", "name": "Distributed Systems", "description": "Term 1 class space", "class_code": "ABCD12", "is_public": false, "is_verified": false, "creator": 42, "creator_name": "Asha Mrema", "member_count": 18, "is_member": true, "user_role": "lecturer", "join_qr_payload": { "type": "class_join", "class_code": "ABCD12", "class_name": "Distributed Systems", "join_endpoint": "/api/v1/classes/join/" }, "created_at": "2026-08-21T09:00:00Z", "updated_at": "2026-08-21T09:00:00Z" }

UploadCreate — multipart POST /uploads/

PartTypeRequiredNotes
filefile bytesYesMaximum 50 MiB.
class_objUUID stringYesTarget class UUID.
file_namestringNoOverrides the client file name used for classification/storage naming.

UploadRead

{ "id": "11111111-2222-3333-4444-555555555555", "file_name": "week-01-notes.pdf", "file_type": "document", "file_size": 248010, "file_code": "ABC123", "file": "uploads/42/week-01-notes.pdf", "file_url": "https://media.example.com/uploads/42/week-01-notes.pdf", "uploader": 42, "uploader_name": "Asha Mrema", "class_obj": "11111111-2222-3333-4444-555555555555", "class_name": "Distributed Systems", "is_deleted": false, "deleted_at": null, "created_at": "2026-08-21T09:00:00Z", "updated_at": "2026-08-21T09:00:00Z" }

ShareCreate and ShareRead

{"file_code":"ABC123","shared_with_id":42,"message":"Please review"}

POST /sharing/bulk/ changes shared_with_id to user_ids, an array whose length must be between 1 and 50. A share detail includes id, file metadata, sender/recipient names and IDs, status, message, shared_at, accepted_at, rejected_at, and can_access.

ScheduleEventWrite

{ "title": "Lecture", "description": "Optional agenda", "location": "Room A", "start_at": "2026-09-01T08:00:00Z", "end_at": "2026-09-01T10:00:00Z", "event_type": "class", "recurrence": "weekly", "days": ["monday"], "reminder_minutes": 30 }

title, start_at, and end_at are the meaningful required event values. start_at and end_at use RFC3339. The recurrence handler understands daily, weekly, and monthly values.

AssignmentWrite

{ "title": "Network report", "description": "Research a protocol", "instructions": "Submit a concise report", "attachment": "uploads/42/brief.pdf", "due_date": "2026-09-10T16:00:00Z", "max_score": 100, "is_active": true, "allow_late_submission": false }

The request decoder accepts the assignment resource. The path class UUID is authoritative and replaces a caller-supplied class_obj. Read objects also include id, assignment_code, class_obj, created_by, submission_count, my_submission_status, and timestamps.

SubmissionWrite and GradeWrite

{"response_text":"My completed answer","attachment":"uploads/42/answer.pdf","status":"submitted"}
{"score":85,"feedback":"Strong reasoning","action":"grade"}

status may only be draft or submitted. Grade action may only be grade or return.

AI, search, SMS, and agent schemas

AI Go API

OperationExact request bodyNotable validation/error
Save settings{"api_key":"provider-key","chat_model":"model-name"}chat_model is optional; read responses mask keys.
Chat{"message":"Summarize the class","conversation_id":"optional UUID","class_id":"optional UUID"}message is mandatory and at most 2,000 characters.
Upload statusNo body.Returns an existing job or { "status":"not_started", "chunks_created":0 }.
Global searchNo body; send q, optional categories, and limit as query parameters.Main q needs at least 2 characters; categories are limited to users, classes, files, friends, and library; limit caps at 50.
SuggestionsNo body; q and optional limit query parameters.Suggestion limit caps at 10.
SMS top-up{"amount":100}Invalid amount or missing account is a handler error; delivery list limit caps at 100.

AI indexer request and error schema

// POST /v1/index/uploads/{upload_id} {"force":false} // POST /v1/index/process-due {"limit":100,"include_done":false}
EndpointError statusFastAPI body
Protected indexer route401{ "detail":"Invalid service token" }
Job status with unknown upload404{ "detail":"AI processing job not found" }
Job/status operation with unavailable database503{ "detail":"<runtime dependency message>" }
process-due invalid limit422FastAPI validation detail; limit must be 1–1000.

Agent proxy and MCP schemas

{ "method": "POST", "path": "/api/v1/classes/join/", "user_token": "<end-user Kibegi access JWT>", "params": null, "body": {"class_code":"ABCD12"}, "confirm": true }
ConditionStatusResponse
Gateway ingress token is wrong401{ "detail":"Invalid gateway token" }
Path falls outside the migrated allowlist400{ "detail":"Path is outside the exposed Kibegi API namespace" }
Non-GET proxy or tool call lacks confirmation400{ "detail":"Mutation requires confirm=true" }
Downstream Go response, including error200 from gateway transport{ "http_status": <Go status>, "response": <Go payload> }
Typed upload_file content is invalid base64Tool validation failurecontent_base64 is invalid before downstream traffic.
Typed upload_file bytes exceed 50 MiBTool validation failureFile exceeds the 50MB Go API limit before downstream traffic.

Status-code guide for UI states

StatusUI or agent behavior
200Render the returned detail, state transition, or list.
201Treat as a newly-created record; update local lists from data.
202Show a queued/processing state; for bulk shares, use the returned processing metadata.
400Present field/domain validation from the message, errors, or FastAPI detail; do not retry unchanged input.
401Refresh/re-authenticate the end user, or correct the private service token.
403Preserve the current UI state and show a permissions response; retries will not help until role/access changes.
404Remove or refresh stale route/resource state.
405Client used an unsupported method; treat as an integration bug.
409Resolve duplicate/conflicting state rather than blindly retrying.
422AI indexer/FastAPI body or path failed schema validation.
429Back off; respect the operation’s OTP or global API rate limit.
500, 502, 503Show a recoverable dependency/server error and retry with bounded backoff only for safe operations.
Last updated on