Appearance
schedule
7 endpoints.
GET /api/v1/schedule/channels
List Channels
The channel registry with this site's resolved local + portal links.
200 — Successful Response
json
{
"additionalProperties": true,
"type": "object",
"title": "Response List Channels Api V1 Schedule Channels Get"
}GET /api/v1/schedule/creatives/{kind}/{ref}/thumb
Creative Thumb
A downscaled copy of one creative — every image the calendar draws.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
kind | path | yes | string | |
ref | path | yes | string |
200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}GET /api/v1/schedule/creatives
List Creatives
The site's ad-creative library — what the calendar's left rail lists and what a person drags onto a date.
Two populations, newest first, because two apps produce ad artwork and both are legitimately "a creative" to plan a flight around:
ad_run— anad_run_assetsrow of kindcreativefrom the AI ad pipeline (Meta Ads → Create Ad);design— a Graphic Designerdesign_asset.
Both hand back a thumbnail URL on this router's own authenticated route (see creative_thumb above) rather than each app's own path, so every image the calendar draws is downscaled, tenant-checked, and reachable on a box that has no /design-assets/ nginx alias. auth: true on both is what tells the browser to fetch through the bearer client rather than as a bare <img src>; it is carried per-creative, not assumed, because it also travels onto the schedule entry and has to keep meaning what it meant then.
Each source is queried defensively. The two apps that own these tables are separately installable, so on a site with neither the table is simply absent — that is an empty rail, not a 500 (cf. the reseller_users lesson: an unguarded query on an optional table takes the whole page down).
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
limit | query | no | integer |
200 — Successful Response
json
{
"type": "object",
"additionalProperties": true,
"title": "Response List Creatives Api V1 Schedule Creatives Get"
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}GET /api/v1/schedule/events
List Events
Planned + live campaign events overlapping [start, end].
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
start | query | yes | string | |
end | query | yes | string | |
channel | query | no | ||
include_live | query | no | boolean |
200 — Successful Response
json
{
"type": "object",
"additionalProperties": true,
"title": "Response List Events Api V1 Schedule Events Get"
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}POST /api/v1/schedule/events
Create Event
Request body
json
{
"properties": {
"title": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"title": "Title"
},
"channel": {
"type": "string",
"title": "Channel",
"default": "other"
},
"status": {
"type": "string",
"title": "Status",
"default": "planned"
},
"start_at": {
"type": "string",
"format": "date-time",
"title": "Start At"
},
"end_at": {
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "null"
}
],
"title": "End At"
},
"all_day": {
"type": "boolean",
"title": "All Day",
"default": false
},
"recurrence": {
"type": "string",
"title": "Recurrence",
"default": "none"
},
"objective": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Objective"
},
"audience": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Audience"
},
"budget": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
},
{
"type": "null"
}
],
"title": "Budget"
},
"source_grid": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Grid"
},
"source_record_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Record Id"
},
"source_label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Label"
},
"local_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Local Url"
},
"portal_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Portal Url"
},
"colour": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Colour"
},
"notes": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Notes"
},
"creative_kind": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Creative Kind"
},
"creative_ref": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Creative Ref"
},
"creative_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Creative Url"
},
"creative_auth": {
"type": "boolean",
"title": "Creative Auth",
"default": false
},
"creative_label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Creative Label"
},
"chat_tested": {
"type": "boolean",
"title": "Chat Tested",
"default": false
},
"checkout_tested": {
"type": "boolean",
"title": "Checkout Tested",
"default": false
},
"activation_tested": {
"type": "boolean",
"title": "Activation Tested",
"default": false
}
},
"type": "object",
"required": [
"title",
"start_at"
],
"title": "EventIn"
}201 — Successful Response
json
{
"type": "object",
"additionalProperties": true,
"title": "Response Create Event Api V1 Schedule Events Post"
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}PATCH /api/v1/schedule/events/{event_id}
Update Event
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
event_id | path | yes | string |
Request body
json
{
"properties": {
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 255,
"minLength": 1
},
{
"type": "null"
}
],
"title": "Title"
},
"channel": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Channel"
},
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Status"
},
"start_at": {
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "null"
}
],
"title": "Start At"
},
"end_at": {
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "null"
}
],
"title": "End At"
},
"all_day": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "All Day"
},
"recurrence": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Recurrence"
},
"objective": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Objective"
},
"audience": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Audience"
},
"budget": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
},
{
"type": "null"
}
],
"title": "Budget"
},
"source_grid": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Grid"
},
"source_record_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Record Id"
},
"source_label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Label"
},
"local_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Local Url"
},
"portal_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Portal Url"
},
"colour": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Colour"
},
"notes": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Notes"
},
"creative_kind": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Creative Kind"
},
"creative_ref": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Creative Ref"
},
"creative_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Creative Url"
},
"creative_auth": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Creative Auth"
},
"creative_label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Creative Label"
},
"chat_tested": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Chat Tested"
},
"checkout_tested": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Checkout Tested"
},
"activation_tested": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Activation Tested"
}
},
"type": "object",
"title": "EventPatch"
}200 — Successful Response
json
{
"type": "object",
"additionalProperties": true,
"title": "Response Update Event Api V1 Schedule Events Event Id Patch"
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}DELETE /api/v1/schedule/events/{event_id}
Delete Event
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
event_id | path | yes | string |
204 — Successful Response
422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}