API reference: overview
The TwistCue Admin API is a NestJS service exposing REST endpoints under /v1/admin/*. All admin endpoints are protected by AdminJwtGuard + PermissionsGuard.
Base URL
Section titled “Base URL”- Dev:
http://localhost:3000/v1 - Staging/Prod:
https://api.twistcue.connectorme.com/v1(subject to change)
Versioning
Section titled “Versioning”- Prefix
/v1. New majors introduced when breaking mobile contracts. - Admin endpoints under
/v1/admin/*. Public endpoints under/v1/*(e.g./v1/feed,/v1/flags).
Authentication
Section titled “Authentication”- Login:
POST /v1/admin/auth/login→ returns{access_token, admin}. - Token is a JWT with
sub,role,permissions[],token_version,exp(12h). - Send on subsequent requests as:
- HTTP header:
Authorization: Bearer <token>or - Cookie:
tc_admin_token=<token>(set automatically on login response).
- HTTP header:
Authorization
Section titled “Authorization”Every admin endpoint declares required permissions via @RequirePermission('resource:action', ...). The PermissionsGuard:
- Reads
req.admin.permissionsfrom the JWT. - Runs OR semantics across the declared perms.
- Returns
403 insufficient_permissionswith{ required: [...] }on failure. *in the granted list short-circuits to allow.
Errors
Section titled “Errors”Standard error shape:
{ "statusCode": 403, "error": "insufficient_permissions", "required": ["catalog:write"]}Common error codes:
| Code | HTTP | Meaning |
|---|---|---|
invalid_credentials | 401 | Bad email/password. |
token_expired / token_invalid | 401 | JWT rejected. |
admin_disabled | 403 | Admin is_active=false. |
insufficient_permissions | 403 | Permission check failed. |
approver_must_differ | 403 | Two-person rule violated. |
support_daily_cap_exceeded | 400 | 500-coin support cap. |
insufficient_balance | 400 | Coin deduct would go negative. |
invalid_transition | 400 | Publish state machine rejects the move. |
in_use | 409 | Delete refused because references exist. |
not_found | 404 | Standard. |
Request/response conventions
Section titled “Request/response conventions”- JSON, camelCase.
- UTC ISO-8601 for datetimes.
- cents for money, coins (integer) for coin values (1 coin = $0.01).
- Cursor pagination:
?cursor=<opaque>&limit=<int>. Response includesnextCursor: string | null. - All mutating endpoints are idempotent-safe where they can be (server dedup on
client_dedup_keyfor events) but do NOT guarantee full idempotency: client should retry cautiously.
Rate limits
Section titled “Rate limits”- Login endpoint: 10 attempts / 5 min / IP.
- Other admin endpoints: 300 req / min / admin (generous: this is an operator surface).
- CSV export streaming does not count against the rate limit.
- Every mutating endpoint writes an
AuditLogrow in the same transaction. - Reads are not audited (too high volume).
Sections
Section titled “Sections”Read the section that matches the module you’re calling:
- Auth
- Catalog
- Media
- Publishing
- Curation
- Users, wallet, support
- Payments & refunds
- Monetization (pricing, packages, promos, subscriptions, economy)
- Analytics
- Engagement (segments, push, moderation, flags, rewards, settings)
- System (admins, roles, approvals, audit, stats)
- Public endpoints affected by admin state