REST API Reference
Complete reference for the TendedLoop REST API. 285+ endpoints across 15 modules for feedback collection, task management, analytics, and facility administration.
Overview
The TendedLoop REST API provides programmatic access to all platform capabilities. Every response follows a consistent JSON envelope format. All data is tenant-scoped — authenticated requests can only access data belonging to their tenant.
The API serves three categories of consumers: public endpoints (anonymous QR feedback, status pages), authenticated endpoints (tasks, dashboards, admin), and integration endpoints (API keys, webhooks).
https://api.tendedloop.com.
Base URL & Response Format
Base URL
https://api.tendedloop.com
Response Envelope
Every response uses a consistent JSON envelope. The success field indicates whether the request succeeded. On success, data contains the result. On failure, error and code describe what went wrong.
Success response
{
"success": true,
"data": {
"id": "clx9abc...",
"name": "Headquarters",
"createdAt": "2026-01-15T10:30:00.000Z"
}
}
Error response
{
"success": false,
"error": "QR code not found or not configured",
"code": "NOT_FOUND"
}
Authentication
TendedLoop supports two authentication methods. For a detailed guide, see the Authentication documentation.
JWT Bearer Token
Obtain a token by logging in via POST /api/auth/login. Include it in subsequent requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
API Key
Generate an API key in the dashboard or via the API. Include it in the X-API-Key header:
X-API-Key: tl_k_abc123...
POST /api/auth/refresh) to obtain new tokens without re-authenticating.
Pagination
List endpoints support cursor-based pagination via query parameters.
| Parameter | Default | Description |
|---|---|---|
page |
1 |
Page number (1-indexed) |
pageSize |
20 |
Items per page (max 100) |
Paginated response
{
"success": true,
"data": [...],
"total": 142,
"page": 1,
"pageSize": 20,
"totalPages": 8
}
Core Endpoints
The most commonly used endpoints, organized by module. All paths are relative to the base URL.
Feedback (Public)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/feedback/amenity/:qrCode |
None | Get amenity info for a QR code |
| POST | /api/feedback |
None | Submit anonymous feedback |
| POST | /api/feedback/upload-url |
None | Get signed URL for image upload |
Example: Submit feedback
curl -X POST https://api.tendedloop.com/api/feedback \ -H "Content-Type: application/json" \ -d '{ "qrCode": "TL-ABC123", "rating": 4, "comment": "Very clean, well maintained", "issues": [] }'
Status (Public)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/status/:qrCode |
None | Get status items for an amenity |
| POST | /api/status/:qrCode/report |
None | Report a status issue |
Tasks (JWT)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/tasks |
JWT | List tasks (filterable by status, assignee, building) |
| GET | /api/tasks/:id |
JWT | Get task details |
| PATCH | /api/tasks/:id/status |
JWT | Update task status (OPEN, IN_PROGRESS, DONE) |
Example: Update task status
curl -X PATCH https://api.tendedloop.com/api/tasks/clx9abc.../status \ -H "Authorization: Bearer eyJhbGci..." \ -H "Content-Type: application/json" \ -d '{ "status": "DONE" }'
Dashboard (JWT, Manager+)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/dashboard/overview |
JWT | Dashboard summary (counts, trends, recent activity) |
| GET | /api/dashboard/feedback |
JWT | Feedback analytics (ratings, trends, heatmaps) |
| GET | /api/dashboard/amenities/performance |
JWT | Amenity performance rankings |
| GET | /api/dashboard/sla |
JWT | SLA compliance metrics |
| GET | /api/dashboard/team-performance |
JWT | Team performance and response times |
Admin: Buildings (JWT, Admin)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/admin/buildings |
Admin | List all buildings |
| POST | /api/admin/buildings |
Admin | Create a building |
| PATCH | /api/admin/buildings/:id |
Admin | Update building details |
| DELETE | /api/admin/buildings/:id |
Admin | Delete a building |
Admin: Amenities (JWT, Admin)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/admin/amenities |
Admin | List amenities (filterable by building, location, type) |
| POST | /api/admin/amenities |
Admin | Create an amenity with auto-generated QR code |
| PATCH | /api/admin/amenities/:id |
Admin | Update amenity details |
Admin: Users (JWT, Admin)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/admin/users |
Admin | List team members |
| POST | /api/admin/users |
Admin | Invite a new team member |
| PATCH | /api/admin/users/:id |
Admin | Update user roles or details |
Admin: Webhooks (JWT, Admin)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/admin/webhooks |
Admin | List configured webhooks |
| POST | /api/admin/webhooks |
Admin | Create a webhook subscription |
Billing (JWT)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/billing/subscription |
JWT | Get current subscription and plan limits |
| POST | /api/billing/checkout |
JWT | Create Stripe checkout session |
| POST | /api/billing/portal |
JWT | Open Stripe customer portal |
Rate Limiting
Rate limits are enforced per IP (public endpoints) or per tenant (authenticated endpoints). When exceeded, the API returns 429 Too Many Requests with the RATE_LIMITED error code.
| Category | Limit | Window |
|---|---|---|
| Feedback submission | 5 requests | per minute per IP |
| Status reporting | 10 requests | per minute per IP |
| Login attempts | 5 requests | per 15 minutes per email |
| Image uploads | 3 requests | per minute per IP |
| Authenticated reads | 100 requests | per minute per tenant |
| Authenticated writes | 30 requests | per minute per tenant |
Error Codes
Error responses include a machine-readable code field. Use this for programmatic error handling rather than parsing the error message.
| Code | HTTP | Description |
|---|---|---|
VALIDATION_ERROR |
400 | Request body or query params failed validation |
UNAUTHORIZED |
401 | Missing or invalid authentication |
FORBIDDEN |
403 | Insufficient role or permissions |
NOT_FOUND |
404 | Resource does not exist or belongs to another tenant |
RATE_LIMITED |
429 | Too many requests; retry after the window resets |
PLAN_LIMIT_REACHED |
403 | Resource limit exceeded for current plan (e.g., max QR codes) |
QR_NOT_CONFIGURED |
404 | QR code exists but is not linked to an amenity |
Plan-Gated Features
Certain API features are only available on specific plans. Requests to plan-gated endpoints on lower plans return 403 with a descriptive error.
| Feature | Minimum Plan | Notes |
|---|---|---|
| Automatic routing rules | Pro | Auto-assign tasks by location/amenity type |
| SLA monitoring | Pro | Response time targets and compliance tracking |
| Webhooks | Business | Real-time event notifications |
| Data export (CSV) | Business | Bulk export feedback, tasks, analytics |
| Task escalation | Business | Auto-escalate overdue tasks |
| PDF reports | Business | Generate formatted PDF reports |
| Shift-based routing | Enterprise | Route tasks by shift schedule |
| SSO (SAML/OIDC) | Enterprise | Single sign-on via Microsoft/Google |
Full Endpoint Count
The API is organized into 15 registered modules plus 3 internal modules. Below is the full breakdown.
| Module | Prefix | Auth | Endpoints |
|---|---|---|---|
| Auth | /api/auth |
Public / JWT | 12 |
| Feedback | /api/feedback |
Public | 5 |
| Status | /api/status |
Public | 4 |
| Tasks | /api/tasks |
JWT | 15 |
| Dashboard | /api/dashboard |
JWT (Manager+) | 20 |
| Admin | /api/admin |
JWT (Admin) | 95 |
| Billing | /api/billing |
JWT / Webhook | 6 |
| Wizard | /api/wizard |
JWT (Admin) | 5 |
| Sharing | /api/sharing |
JWT (Admin) | 18 |
| Operator Registry | /api/operator |
JWT | 12 |
| Scout | /api/scout |
Scout JWT | 40 |
| Slack | /api/slack |
OAuth / Signed | 8 |
| Arena | /api/arena |
Arena JWT | 25 |
| Super Admin | /api/super-admin |
JWT (Super Admin) | 15 |
| System | /api/system |
System Secret | 5 |
| Total | 285+ | ||
Plus 3 internal modules (alerts, routing, export) with no public routes.
Ready to build?
Start integrating with the TendedLoop API in minutes.