Backend API - Design Document - Part II API
=============================
Purpose
This page documents the backend API as a set of resources, requests, and responses.
Scope
VibeCheck has one backend-facing interface; a Slack Bolt runtime that powers the bot.
Formal HTTP contract is maintained in:
documentation/static/openapi.yml.yaml
The rendered version appears in:
docs/api-specification/openapi-spec
API Style
- Protocol: HTTPS/JSON
- Format: REST-style resource endpoints
- Authentication: bearer token for protected endpoints
- Primary resources: prompts, submissions, admin actions, metrics
Resource Overview
| Resource | Description | Access Pattern |
|---|---|---|
| Health | service availability and version metadata | GET /health |
| Prompt | active prompt and prompt delivery data | GET /v1/prompts/today |
| Submission | user response to a prompt | POST /v1/submissions |
| Admin Prompt Dispatch | manual prompt send operation | POST /v1/admin/prompts/force-send |
| Prompt Metrics | prompt usage counts and response counts | GET /v1/metrics/prompts |
Endpoint Summary
| Method | Path | Input | Output |
|---|---|---|---|
GET | /health | none | service status, version, timestamp |
GET | /v1/prompts/today | auth header | active prompt metadata |
POST | /v1/submissions | JSON request body | created submission record |
POST | /v1/admin/prompts/force-send | JSON request body | queued dispatch result |
GET | /v1/metrics/prompts | query parameters and auth header | list of prompt metrics |
Metrics Data
This is the part the critique was asking for: the API specification should clearly show what metrics data exists and how it is accessed through the REST API.
Prompt Metrics Fields
The backend tracks prompt-usage metrics per workspace. Each prompt metric record contains:
teamId: Slack workspace identifierpromptId: unique prompt identifierprompt: prompt texttags: associated topic tagstimesAsked: number of times the prompt has been postedtimesResponded: number of responses recorded for that promptlastAskedAt: timestamp of the most recent send
Metrics Access Pattern
Clients retrieve metrics through:
GET /v1/metrics/prompts?teamId=T12345&limit=20
Example Metrics Response
{
"teamId": "T12345",
"count": 2,
"items": [
{
"promptId": "5",
"prompt": "If you had to swap jobs with a friend for a day, who would it be?",
"tags": ["work_life"],
"timesAsked": 8,
"timesResponded": 5,
"lastAskedAt": "2026-04-13T18:30:00Z"
},
{
"promptId": "12",
"prompt": "Post a photo that captures your current energy.",
"tags": ["photo", "social"],
"timesAsked": 6,
"timesResponded": 2,
"lastAskedAt": "2026-04-12T18:30:00Z"
}
]
}
Request and Response Examples
GET /v1/prompts/today
Response
{
"promptId": "prm_20260330",
"text": "Post a quick lunch update and a photo.",
"channelId": "C01234567",
"opensAt": "2026-03-30T16:00:00Z",
"closesAt": "2026-03-30T16:30:00Z",
"status": "active"
}
POST /v1/submissions
Request
{
"userId": "U12345",
"channelId": "C01234567",
"text": "Lunch break at the student center",
"imageUrl": "https://cdn.example.com/images/submission1.jpg"
}
Response
{
"submissionId": "sub_4f8128",
"promptId": "prm_20260330",
"userId": "U12345",
"channelId": "C01234567",
"text": "Lunch break at the student center",
"imageUrl": "https://cdn.example.com/images/submission1.jpg",
"createdAt": "2026-03-30T16:11:33Z",
"late": false
}
POST /v1/admin/prompts/force-send
Request
{
"channelId": "C01234567",
"promptText": "Share one photo that shows your current vibe.",
"postImmediately": true
}
Response
{
"requestId": "req_7dc2e1",
"status": "queued"
}
Error Contract
Protected endpoints may return:
401 Unauthorizedwhen authentication is missing or invalid403 Forbiddenwhen the caller lacks permission for an admin endpoint400 Bad Requestwhen the input payload is invalid409 Conflictwhen a submission duplicates an existing prompt response500 Internal Server Errorfor unexpected failures