Admin
All admin endpoints use the base URL /v1 and require the requireAdmin middleware. Requests must include a valid Bearer token belonging to an admin or service_role account.
Authorization: Bearer <admin_or_service_role_token>List Users
Section titled “List Users”GET /v1/admin/usersReturns a cursor-paginated list of users. Supports searching by username, first name, or last name.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
search | string | — | Optional. Searches across username, first_name, and last_name. |
cursor | string | — | Cursor value from a previous response for pagination. |
limit | integer | 20 | Number of users to return. Maximum 100. |
Response 200 OK:
{ "users": [ { "id": "uuid", "username": "janedoe", "first_name": "Jane", "last_name": "Doe", "role": "user", "user_status": "active", "verified": true, "type": "creator", "created_at": "2025-01-15T08:30:00.000Z" } ], "next_cursor": "2025-01-10T06:00:00.000Z"}When there are no more results, next_cursor is null.
Get User
Section titled “Get User”GET /v1/admin/users/{id}Returns full details for a single user.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The user’s unique ID. |
Response 200 OK:
{ "user": { "id": "uuid", "username": "janedoe", "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com", "role": "user", "user_status": "active", "verified": true, "type": "creator", "created_at": "2025-01-15T08:30:00.000Z", "updated_at": "2025-06-01T12:00:00.000Z" }}Errors:
| Status | Description |
|---|---|
404 Not Found | No user exists with the given ID. |
Update User
Section titled “Update User”PATCH /v1/admin/users/{id}Updates specific fields on a user record. Only the allowed fields listed below are accepted.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The user’s unique ID. |
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
role | string | No | The user’s role (e.g. user, admin). |
user_status | string | No | Account status (e.g. active, suspended, banned). |
verified | boolean | No | Whether the user is verified. |
type | string | No | User type (e.g. creator, standard). |
Request Example:
{ "role": "admin", "verified": true}Response 200 OK:
{ "user": { "id": "uuid", "username": "janedoe", "role": "admin", "user_status": "active", "verified": true, "type": "creator", "updated_at": "2025-06-02T10:00:00.000Z" }}Errors:
| Status | Description |
|---|---|
404 Not Found | No user exists with the given ID. |
Delete User
Section titled “Delete User”DELETE /v1/admin/users/{id}Permanently deletes a user from Supabase Auth. This cascades to all related data and is irreversible.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The user’s unique ID. |
Response 200 OK:
{ "message": "User deleted"}Errors:
| Status | Description |
|---|---|
404 Not Found | No user exists with the given ID. |
List Posts
Section titled “List Posts”GET /v1/admin/postsReturns a list of posts across all users, with basic author information.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
status | string | — | Optional. Filter by post status (e.g. published, draft, flagged). |
limit | integer | 20 | Number of posts to return. Maximum 100. |
Response 200 OK:
{ "posts": [ { "id": "uuid", "title": "My First Post", "status": "published", "created_at": "2025-06-01T12:00:00.000Z", "author": { "id": "uuid", "username": "janedoe" } } ]}Delete Post
Section titled “Delete Post”DELETE /v1/admin/posts/{id}Removes a post. This is typically used for content moderation.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The post’s unique ID. |
Response 200 OK:
{ "message": "Post removed"}Errors:
| Status | Description |
|---|---|
404 Not Found | No post exists with the given ID. |
Products
Section titled “Products”List Products
Section titled “List Products”GET /v1/admin/productsReturns up to 50 products with seller information. The limit is fixed and not configurable.
Response 200 OK:
{ "products": [ { "id": "uuid", "title": "Digital Art Pack", "price": 29.99, "status": "active", "created_at": "2025-05-20T14:00:00.000Z", "seller": { "id": "uuid", "username": "alexsmith" } } ]}Delete Product
Section titled “Delete Product”DELETE /v1/admin/products/{id}Removes a product listing.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The product’s unique ID. |
Response 200 OK:
{ "message": "Product removed"}Errors:
| Status | Description |
|---|---|
404 Not Found | No product exists with the given ID. |
Reports
Section titled “Reports”List Reports
Section titled “List Reports”GET /v1/admin/reportsReturns reports with reporter information. Can be filtered by resolution status.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
status | string | — | Optional. One of: pending, resolved, dismissed. |
Response 200 OK:
{ "reports": [ { "id": "uuid", "reportable_id": "uuid", "reportable_type": "post", "reason": "Spam content", "description": "This post contains repeated spam links.", "status": "pending", "resolved_by": null, "resolved_at": null, "created_at": "2025-06-10T08:00:00.000Z", "reporter": { "id": "uuid", "username": "mchen" } } ]}Resolve Report
Section titled “Resolve Report”PATCH /v1/admin/reports/{id}Updates a report’s status. Automatically sets resolved_by to the authenticated admin’s ID and resolved_at to the current timestamp.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The report’s unique ID. |
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
status | string | Yes | New status. Must be one of: resolved, dismissed. |
Request Example:
{ "status": "resolved"}Response 200 OK:
{ "report": { "id": "uuid", "reportable_id": "uuid", "reportable_type": "post", "reason": "Spam content", "status": "resolved", "resolved_by": "admin-uuid", "resolved_at": "2025-06-11T10:00:00.000Z" }}Errors:
| Status | Description |
|---|---|
400 Bad Request | Missing status or invalid value. Must be resolved or dismissed. |
404 Not Found | No report exists with the given ID. |
List Ads
Section titled “List Ads”GET /v1/admin/adsReturns up to 50 ad campaigns with owner information. The limit is fixed and not configurable.
Response 200 OK:
{ "ads": [ { "id": "uuid", "title": "Summer Sale Campaign", "status": "pending", "budget": 500, "spent_budget": 120.50, "views_count": 2410, "created_at": "2025-06-01T09:00:00.000Z", "owner": { "id": "uuid", "username": "janedoe" } } ]}Update Ad Status
Section titled “Update Ad Status”PATCH /v1/admin/ads/{id}Approve or reject an ad campaign.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The ad’s unique ID. |
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
status | string | Yes | New status. One of: active, rejected. |
Request Example:
{ "status": "active"}Response 200 OK:
{ "ad": { "id": "uuid", "title": "Summer Sale Campaign", "status": "active", "updated_at": "2025-06-02T14:00:00.000Z" }}Errors:
| Status | Description |
|---|---|
400 Bad Request | Invalid status value. Must be active or rejected. |
404 Not Found | No ad exists with the given ID. |
List Jobs
Section titled “List Jobs”GET /v1/admin/jobsReturns up to 50 job listings with poster information. The limit is fixed and not configurable.
Response 200 OK:
{ "jobs": [ { "id": "uuid", "title": "Senior Frontend Developer", "status": "pending", "location": "Remote", "created_at": "2025-06-05T11:00:00.000Z", "poster": { "id": "uuid", "username": "alexsmith" } } ]}Update Job
Section titled “Update Job”PATCH /v1/admin/jobs/{id}Updates any fields on a job listing. All job fields are allowed.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The job’s unique ID. |
Request Example:
{ "status": "active", "title": "Senior Frontend Developer (Updated)"}Response 200 OK:
{ "job": { "id": "uuid", "title": "Senior Frontend Developer (Updated)", "status": "active", "updated_at": "2025-06-06T09:00:00.000Z" }}Errors:
| Status | Description |
|---|---|
404 Not Found | No job exists with the given ID. |
Categories
Section titled “Categories”List Categories
Section titled “List Categories”GET /v1/admin/categoriesReturns all categories ordered alphabetically by name. Supports hierarchical structure via parent_id.
Response 200 OK:
{ "categories": [ { "id": "uuid", "name": "Art", "parent_id": null, "slug": "art" }, { "id": "uuid", "name": "Digital Art", "parent_id": "uuid", "slug": "digital-art" } ]}Create Category
Section titled “Create Category”POST /v1/admin/categoriesCreates a new category.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name of the category. |
parent_id | uuid | No | ID of the parent category for nesting. |
slug | string | No | URL-friendly slug. Auto-generated from name if omitted. |
Request Example:
{ "name": "Digital Art", "parent_id": "art-category-uuid", "slug": "digital-art"}Response 201 Created:
{ "category": { "id": "uuid", "name": "Digital Art", "parent_id": "art-category-uuid", "slug": "digital-art" }}Errors:
| Status | Description |
|---|---|
400 Bad Request | Missing required name field. |
Update Category
Section titled “Update Category”PATCH /v1/admin/categories/{id}Updates an existing category.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The category’s unique ID. |
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Updated display name. |
parent_id | uuid | No | Updated parent category ID. |
slug | string | No | Updated slug. |
Request Example:
{ "name": "Fine Art"}Response 200 OK:
{ "category": { "id": "uuid", "name": "Fine Art", "parent_id": null, "slug": "fine-art" }}Errors:
| Status | Description |
|---|---|
404 Not Found | No category exists with the given ID. |
Delete Category
Section titled “Delete Category”DELETE /v1/admin/categories/{id}Deletes a category.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The category’s unique ID. |
Response 200 OK:
{ "message": "Category deleted"}Errors:
| Status | Description |
|---|---|
404 Not Found | No category exists with the given ID. |
Blacklist
Section titled “Blacklist”List Blacklist Entries
Section titled “List Blacklist Entries”GET /v1/admin/blacklistReturns all blacklist entries.
Response 200 OK:
{ "entries": [ { "id": "uuid", "type": "email", "value": "spammer@example.com", "reason": "Repeated spam violations", "created_at": "2025-05-01T10:00:00.000Z" }, { "id": "uuid", "type": "ip", "value": "192.168.1.100", "reason": null, "created_at": "2025-05-15T14:30:00.000Z" } ]}Create Blacklist Entry
Section titled “Create Blacklist Entry”POST /v1/admin/blacklistAdds a new entry to the blacklist.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Type of entry (e.g. email, ip, domain, username). |
value | string | Yes | The value to blacklist. |
reason | string | No | Reason for blacklisting. |
Request Example:
{ "type": "email", "value": "spammer@example.com", "reason": "Repeated spam violations"}Response 201 Created:
{ "entry": { "id": "uuid", "type": "email", "value": "spammer@example.com", "reason": "Repeated spam violations", "created_at": "2025-06-12T08:00:00.000Z" }}Errors:
| Status | Description |
|---|---|
400 Bad Request | Missing required type or value field. |
Delete Blacklist Entry
Section titled “Delete Blacklist Entry”DELETE /v1/admin/blacklist/{id}Removes an entry from the blacklist.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The blacklist entry’s unique ID. |
Response 200 OK:
{ "message": "Blacklist entry deleted"}Errors:
| Status | Description |
|---|---|
404 Not Found | No blacklist entry exists with the given ID. |
Content Filters (Censors)
Section titled “Content Filters (Censors)”List Censors
Section titled “List Censors”GET /v1/admin/censorsReturns all content filter patterns.
Response 200 OK:
{ "censors": [ { "id": "uuid", "pattern": "badword", "replacement": "****", "created_at": "2025-04-20T12:00:00.000Z" }, { "id": "uuid", "pattern": "offensive\\s?phrase", "replacement": "[removed]", "created_at": "2025-05-10T09:00:00.000Z" } ]}Create Censor
Section titled “Create Censor”POST /v1/admin/censorsAdds a new content filter pattern.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
pattern | string | Yes | Regex pattern to match against content. |
replacement | string | No | Replacement text. Defaults to empty string if omitted. |
Request Example:
{ "pattern": "badword", "replacement": "****"}Response 201 Created:
{ "censor": { "id": "uuid", "pattern": "badword", "replacement": "****", "created_at": "2025-06-12T08:30:00.000Z" }}Errors:
| Status | Description |
|---|---|
400 Bad Request | Missing required pattern field. |
Delete Censor
Section titled “Delete Censor”DELETE /v1/admin/censors/{id}Removes a content filter pattern.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The censor entry’s unique ID. |
Response 200 OK:
{ "message": "Censor deleted"}Errors:
| Status | Description |
|---|---|
404 Not Found | No censor exists with the given ID. |
Creator Verification (Authorship Requests)
Section titled “Creator Verification (Authorship Requests)”List Authorship Requests
Section titled “List Authorship Requests”GET /v1/admin/authorship-requestsReturns all creator verification requests with the associated user profile.
Response 200 OK:
{ "authorship_requests": [ { "id": "uuid", "user_id": "uuid", "status": "pending", "reviewed_by": null, "reviewed_at": null, "created_at": "2025-06-01T10:00:00.000Z", "user": { "id": "uuid", "username": "janedoe", "first_name": "Jane", "last_name": "Doe", "avatar_url": "https://cdn.example.com/avatars/janedoe.jpg" } } ]}Review Authorship Request
Section titled “Review Authorship Request”PATCH /v1/admin/authorship-requests/{id}Approves or rejects a creator verification request. Automatically sets reviewed_by to the authenticated admin’s ID and reviewed_at to the current timestamp. If approved, the user’s verified field is set to true.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | The authorship request’s unique ID. |
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
status | string | Yes | New status. Must be one of: approved, rejected. |
Request Example:
{ "status": "approved"}Response 200 OK:
{ "authorship_request": { "id": "uuid", "user_id": "uuid", "status": "approved", "reviewed_by": "admin-uuid", "reviewed_at": "2025-06-02T14:30:00.000Z" }}Errors:
| Status | Description |
|---|---|
400 Bad Request | Missing status or invalid value. Must be approved or rejected. |
404 Not Found | No authorship request exists with the given ID. |