Save a CalDAV connection through Nexus and a Calendar reference.
Action: app_topolo_calendar.external_calendars.caldav.create · POST /api/admin/external-calendars/caldav
Declared permission: app_topolo_calendar.availability:write. For authorized Calendar users; permissions and resource access still apply.
Before you start
- Use the current credential to confirm the production organization and inspect this exact action before preparing a call.
- Declared permission: app_topolo_calendar.availability:write. Permission discovery is not a grant.
- Discover the authorized Calendar workspace and pass it as resourceType=workspace/resourceId separately from this action input. Calendar records and IDs are scoped to the selected host/workspace.
- Validate and plan the exact payload, obtain effect-specific authorization, then execute unchanged only in a separately authorized operational task. Do not run these synthetic inputs.
Inputs and field meanings
| Field | Presence | Declared constraint | Meaning |
|---|---|---|---|
accountEmail | required | string | Intended external-calendar account email; a label/identity input, not evidence the provider account is connected. |
displayName | optional | nullable/union | Host or external calendar display name. host.update requires it; external-calendar displayName is optional. |
calendarUrl | required | string | HTTPS CalDAV calendar URL. A syntactically valid URL is not successful provider authentication. |
username | required | string | CalDAV username sent through the authorized credential channel; examples use synthetic values only. |
password | required | string | CalDAV app password/credential. Never persist real values in guides, ordinary logs or handover records. |
Worked request and response
Source-reviewed illustration only. Nothing below was executed; all identifiers, counts, states, credentials and URLs are synthetic. Replace identifiers through discovery before any separately authorized call.
Resource context: workspace; it is not an extra action input field.
Illustrative action input:
{
"accountEmail": "host@example.com",
"calendarUrl": "https://calendar.example.com/dav/example/",
"username": "illustrative-user",
"password": "ILLUSTRATIVE_APP_PASSWORD",
"displayName": "Example CalDAV"
}
Illustrative HTTP 201 source response:
{
"externalCalendar": {
"id": "cal_example",
"hostId": "hst_example",
"provider": "caldav",
"accountEmail": "host@example.com",
"displayName": "Example busy calendar",
"providerCalendarId": "https://calendar.example.com/dav/example/",
"nexusConnectionId": "connection_example",
"connectionStatus": "active",
"connectionStatusReason": null,
"lastSyncedAt": null,
"status": "active",
"syncCursor": null,
"lastError": null,
"createdAt": "2026-11-01T00:00:00.000Z",
"updatedAt": "2026-11-01T00:00:00.000Z"
}
}
The active Nexus label and saved ID do not prove provider authentication or sync succeeded. lastSyncedAt remains null here. The password is visibly synthetic; never retain a real password in a guide, transcript or log.
The illustrative response passes the declared structural schema. This establishes only schema compatibility, not deployed shape, values, authorization or business outcome.
Effects and verification
- Saves a CalDAV credential/identity to Nexus and upserts its Calendar connection reference.
- The reviewed handler does not perform a successful CalDAV read before returning.
- Read external_calendars.list and separately authorize sync; verify actual busy-time and provider status afterward.
Refusals and recovery
Selected source refusals are listed below; runtime middleware can return additional structured errors.
| HTTP | Error | Supported response |
|---|---|---|
| 403 | forbidden | Reconcile the declared permission, organization and verified resource grant with the legitimate access owner; do not switch context to bypass a refusal. |
| 404 | no_host | Read host.get; if it returns host:null, create the intended workspace host through host.update before retrying. |
| 400 | invalid_caldav_url | Use an HTTPS CalDAV calendar URL. |
| 400 | caldav_credentials_required | Provide credentials through the authorized secret input channel. |
| 502 | caldav_connection_unavailable | Preserve request evidence and reconcile saved Nexus/Calendar state before any retry. |
Recovery: After reconciling both Nexus and Calendar references, disconnect only the intended connection. A partial save is not permission to create duplicates or delete another owner’s connection.
After an uncertain mutation, reconcile the named records and provider/delivery evidence before repeating it.
Related actions
app_topolo_calendar.external_calendars.list: Discover external calendar IDs, connection state and sync history.app_topolo_calendar.external_calendars.sync: Replace an external calendar’s imported busy-time snapshot.app_topolo_calendar.external_calendars.delete: Disconnect a calendar and remove its local busy-time effect.
Declared schemas and provenance
The hidden action guide carries these exact current declared schemas. They are not rewritten to make the illustrations pass.
Input schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"accountEmail": {
"type": "string",
"format": "email",
"pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
},
"displayName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"calendarUrl": {
"type": "string",
"format": "uri"
},
"username": {
"type": "string",
"minLength": 1
},
"password": {
"type": "string",
"minLength": 1
}
},
"required": [
"accountEmail",
"calendarUrl",
"username",
"password"
],
"additionalProperties": false
}
Output schema:
{
"type": "object",
"title": "Connect CalDAV calendar response",
"description": "Operation result returned by external_calendars.caldav.create.",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
},
"data": {
"oneOf": [
{
"type": "object",
"title": "external record",
"properties": {
"id": {
"type": "string",
"description": "Stable identifier when the external exposes one."
}
},
"additionalProperties": true
},
{
"type": "object",
"additionalProperties": true
}
]
},
"result": {
"type": "object",
"additionalProperties": true
},
"message": {
"type": "string"
}
},
"additionalProperties": true,
"x-topolo-contract-source": "derived-action-metadata",
"x-topolo-contract-precision": "structural"
}
Source: TopoloCalendar@b378ceb73800ee1d1e6c4ff6f0b4179918cf632c, apps/api/src/routes/admin-external-calendars.ts. Current catalog metadata and source were compared without executing the application.
- Source-reviewed synthetic input/response; not captured or executed.
- Source revision is not proof of current deployment, caller access, provider connection or notification delivery.
- The illustrative response passes the declared structural schema. This establishes only schema compatibility, not deployed shape, values, authorization or business outcome.