openapi: 3.1.0
info:
title: Silicon Remind API
version: 0.1.0
description: Durable Silicon reminders with organization-wide read access, owner-Silicon mutations,
IAM application sessions and isolated test environments. Test requests use X-Remind-Test-Key plus
a test IAM identity; they never fall through to production.
servers:
- url: https://backend.remind.teamofsilicons.com/api/v1
security:
- bearerAuth: []
tags:
- name: Schedules
- name: Executions
paths:
/schedules:
get:
tags:
- Schedules
operationId: listSchedules
summary: List schedules visible to the current actor
description: Current or archived reminders in the authenticated organization, filtered before cursor
pagination. Carbons are read-only; only an owning Silicon may mutate reminders.
parameters:
- $ref: '#/components/parameters/OrgId'
- name: silicon_id
in: query
schema:
$ref: '#/components/schemas/SiliconGlobalId'
- name: section
in: query
description: Product-facing reminder section; current is the default.
schema:
allOf:
- $ref: '#/components/schemas/ScheduleSection'
default: current
- name: status
in: query
schema:
$ref: '#/components/schemas/ScheduleStatus'
- $ref: '#/components/parameters/Cursor'
- $ref: '#/components/parameters/Limit'
- $ref: '#/components/parameters/TestKey'
responses:
'200':
description: Schedules
content:
application/json:
schema:
type: object
required:
- items
properties:
items:
type: array
items:
$ref: '#/components/schemas/Schedule'
next_cursor:
type:
- string
- 'null'
default:
$ref: '#/components/responses/Error'
patch:
tags:
- Schedules
operationId: updateScheduleStatuses
summary: Atomically pause or resume owned current schedules
description: Applies one active or paused status to every requested schedule in the supplied order.
The authenticated Silicon must own every schedule, and every schedule must still be current. Validation
is all-or-nothing; failures leave the complete batch unchanged. The response contains one compact
status result per requested schedule in request order.
parameters:
- $ref: '#/components/parameters/OrgId'
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/TestKey'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleStatusBatchUpdate'
responses:
'200':
description: Schedule status results in request order
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleStatusBatchUpdateResponse'
default:
$ref: '#/components/responses/Error'
post:
tags:
- Schedules
operationId: createSchedule
summary: Create a one-time or recurring schedule for the authenticated Silicon
parameters:
- $ref: '#/components/parameters/OrgId'
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/TestKey'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleCreate'
responses:
'201':
description: Schedule created
content:
application/json:
schema:
$ref: '#/components/schemas/Schedule'
'409':
$ref: '#/components/responses/WebhookNotConfigured'
default:
$ref: '#/components/responses/Error'
/schedules/{schedule_id}:
parameters:
- $ref: '#/components/parameters/OrgId'
- $ref: '#/components/parameters/ScheduleId'
get:
tags:
- Schedules
operationId: getSchedule
summary: Get an IAM-visible schedule
description: Inaccessible identifiers return the same not-found response as absent identifiers.
responses:
'200':
description: Schedule
content:
application/json:
schema:
$ref: '#/components/schemas/Schedule'
default:
$ref: '#/components/responses/Error'
parameters:
- $ref: '#/components/parameters/TestKey'
patch:
tags:
- Schedules
operationId: updateSchedule
summary: Update a schedule owned by the authenticated Silicon
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/TestKey'
requestBody:
required: true
content:
application/json:
schema:
type: object
minProperties: 1
additionalProperties: false
properties:
text:
type: string
minLength: 1
timezone:
type: string
description: IANA time-zone identifier
kind:
$ref: '#/components/schemas/ScheduleKind'
cron:
type: string
description: Five-field Linux cron expression
status:
$ref: '#/components/schemas/MutableScheduleStatus'
responses:
'200':
description: Updated schedule
content:
application/json:
schema:
$ref: '#/components/schemas/Schedule'
default:
$ref: '#/components/responses/Error'
delete:
tags:
- Schedules
operationId: archiveSchedule
summary: Archive a schedule owned by the authenticated Silicon for 45 days
responses:
'204':
description: Archived, or already archived
default:
$ref: '#/components/responses/Error'
parameters:
- $ref: '#/components/parameters/TestKey'
/schedules/{schedule_id}/executions:
get:
tags:
- Executions
operationId: listScheduleExecutions
summary: List execution history for an IAM-visible schedule
description: The parent schedule's IAM-projected owner visibility is enforced before pagination.
parameters:
- $ref: '#/components/parameters/OrgId'
- $ref: '#/components/parameters/ScheduleId'
- $ref: '#/components/parameters/Cursor'
- $ref: '#/components/parameters/Limit'
- $ref: '#/components/parameters/TestKey'
responses:
'200':
description: Execution history
content:
application/json:
schema:
type: object
required:
- items
properties:
items:
type: array
items:
$ref: '#/components/schemas/Execution'
next_cursor:
type:
- string
- 'null'
default:
$ref: '#/components/responses/Error'
/auth/login:
post:
operationId: authLogin
summary: Exchange an IAM short-lived token
parameters:
- $ref: '#/components/parameters/TestKey'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
default: &id001
$ref: '#/components/responses/Error'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
slt: &id002
type: string
writeOnly: true
required:
- slt
security: []
description: 'App credentials remain on the server. Responses containing tokens use Cache-Control:
no-store. In a sandbox all IAM requests carry the linked IAM environment key and test Application
credential.'
/auth/refresh:
post:
operationId: authRefresh
summary: Rotate an application refresh token
parameters:
- $ref: '#/components/parameters/TestKey'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
default: *id001
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
refresh_token: *id002
required:
- refresh_token
security: []
description: 'App credentials remain on the server. Responses containing tokens use Cache-Control:
no-store. In a sandbox all IAM requests carry the linked IAM environment key and test Application
credential.'
/auth/logout:
post:
operationId: authLogout
summary: Revoke an application token or refresh family
parameters:
- $ref: '#/components/parameters/TestKey'
responses:
'204':
description: Success
default: *id001
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
token: *id002
required:
- token
security: []
description: 'App credentials remain on the server. Responses containing tokens use Cache-Control:
no-store. In a sandbox all IAM requests carry the linked IAM environment key and test Application
credential.'
/auth/me:
get:
operationId: getIdentity
summary: Read current IAM organization authority
parameters:
- &id003
$ref: '#/components/parameters/OrgId'
- $ref: '#/components/parameters/TestKey'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Identity'
default: *id001
/webhook:
get:
operationId: getWebhook
summary: Read the owning Silicon delivery endpoint
parameters:
- *id003
- $ref: '#/components/parameters/TestKey'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/DestinationInfo'
default: *id001
put:
operationId: configureWebhook
summary: Configure the owning Silicon Hook endpoint
parameters:
- *id003
- $ref: '#/components/parameters/TestKey'
responses:
'201': &id004
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/DestinationReceipt'
default: *id001
'200': *id004
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DestinationInput'
delete:
operationId: disableWebhook
summary: Disable the owning Silicon delivery endpoint
parameters:
- *id003
- $ref: '#/components/parameters/TestKey'
responses:
'204':
description: Success
default: *id001
/silicons:
get:
operationId: listSilicons
summary: List registered Silicons in the organization
parameters:
- *id003
- &id005
name: after
in: query
schema: &id007
type: string
format: uuid
- &id006
name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 50
- $ref: '#/components/parameters/TestKey'
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/Silicon'
next_cursor:
type:
- string
- 'null'
required:
- items
default: *id001
/test-environments:
get:
operationId: listTestEnvironments
summary: List organization-owned environments
parameters:
- *id003
- *id005
- *id006
- name: include_deleted
in: query
schema:
type: boolean
default: false
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/TestEnvironment'
next_cursor:
type:
- string
- 'null'
required:
- items
default: *id001
post:
operationId: createTestEnvironment
summary: Create an empty IAM-bound test environment
parameters:
- *id003
responses:
'201':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/EnvironmentCreated'
default: *id001
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateTestEnvironment'
/test-environments/{id}:
get:
operationId: getTestEnvironment
summary: Read environment metadata
parameters:
- *id003
- &id008
name: id
in: path
required: true
schema: *id007
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/TestEnvironment'
default: *id001
delete:
operationId: deleteTestEnvironment
summary: Retire an environment for 30-day recovery
parameters:
- *id003
- *id008
responses:
'204':
description: Success
default: *id001
/test-environments/{id}/key:
get:
operationId: getEnvironmentKey
summary: Retrieve the active key
parameters:
- *id003
- *id008
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/EnvironmentKey'
default: *id001
description: 'Restricted to the creator or a current organization owner/admin. Keys are retrievable,
encrypted at rest and returned with Cache-Control: no-store.'
/test-environments/{id}/key-rotations:
post:
operationId: rotateEnvironmentKey
summary: Rotate and revoke the previous key
parameters:
- *id003
- *id008
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/EnvironmentKey'
default: *id001
description: 'Restricted to the creator or a current organization owner/admin. Keys are retrievable,
encrypted at rest and returned with Cache-Control: no-store.'
/test-environments/{id}/restorations:
post:
operationId: restoreEnvironment
summary: Recover a deleted environment with a new key
parameters:
- *id003
- *id008
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/EnvironmentKey'
default: *id001
description: 'Restricted to the creator or a current organization owner/admin. Keys are retrievable,
encrypted at rest and returned with Cache-Control: no-store.'
/testing-environment:
get:
operationId: currentEnvironment
summary: Describe the selected sandbox
parameters: []
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/TestEnvironment'
default: *id001
security:
- testKeyAuth: []
description: Requires the Remind environment key only. Omitting it returns test_environment_required.
Cleaning does not clean the linked IAM environment. A sandbox permits at most 100 retained reminders;
inactivity retires it after 15 days.
/testing-environment/cleanings:
post:
operationId: cleanEnvironment
summary: Atomically clear all sandbox data, keeping the IAM binding and root key
parameters: []
responses:
'204':
description: Success
default: *id001
security:
- testKeyAuth: []
description: Requires the Remind environment key only. Omitting it returns test_environment_required.
Cleaning does not clean the linked IAM environment. A sandbox permits at most 100 retained reminders;
inactivity retires it after 15 days.
/health/live:
get:
operationId: healthLive
summary: Check live status
parameters: []
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Health'
default: *id001
security: []
servers:
- url: https://backend.remind.teamofsilicons.com
/health/ready:
get:
operationId: healthReady
summary: Check ready status
parameters: []
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Health'
default: *id001
security: []
servers:
- url: https://backend.remind.teamofsilicons.com
/webhook/:
post:
operationId: receiveIamWebhook
summary: Receive exact-byte signed IAM lifecycle events
parameters:
- name: X-Silicon-IAM-Event-Id
in: header
required: true
schema: &id009
type: string
- name: X-Silicon-IAM-Timestamp
in: header
required: true
schema: *id009
- name: X-Silicon-IAM-Key-Version
in: header
required: true
schema: *id009
- name: X-Silicon-IAM-Signature
in: header
required: true
schema: *id009
responses:
'202':
description: Success
content:
application/json:
schema:
type: object
properties:
receipt_id: *id007
status: *id009
required:
- receipt_id
- status
default: *id001
requestBody:
required: true
content:
application/json:
schema:
type: object
security: []
servers:
- url: https://backend.remind.teamofsilicons.com
description: Authenticates X-Silicon-IAM-Event-Id, X-Silicon-IAM-Timestamp, X-Silicon-IAM-Key-Version
and X-Silicon-IAM-Signature through the official verifier. Testing envelopes route only to linked
active Remind sandboxes after signature and IAM-key verification. Root keys are never persisted
in event payloads.
/testing-environment/iam:
put:
operationId: configureEnvironmentIam
summary: Install or rotate the sandbox IAM Application credential
security: []
parameters:
- $ref: '#/components/parameters/TestKey'
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required:
- iam_app_secret
properties:
iam_app_secret:
type: string
writeOnly: true
responses:
'204':
description: Credential verified in the bound IAM test world and encrypted at rest
default:
$ref: '#/components/responses/Error'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: IAM Remind-audience application token
testKeyAuth:
type: apiKey
in: header
name: X-Remind-Test-Key
description: 32-character Remind root key. Selects an isolated test environment; ordinary actions
still require a test IAM access token.
parameters:
OrgId:
name: X-Org-ID
in: header
required: true
schema:
$ref: '#/components/schemas/OrgId'
ScheduleId:
name: schedule_id
in: path
required: true
schema:
type: string
format: uuid
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
schema:
type: string
minLength: 8
maxLength: 255
Cursor:
name: cursor
in: query
schema:
type: string
Limit:
name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
TestKey:
name: X-Remind-Test-Key
in: header
required: false
description: Optional sandbox selector. Invalid, expired or revoked keys fail closed. Environment
management routes reject this header.
schema:
type: string
pattern: ^[a-zA-Z0-9]{32}$
responses:
WebhookNotConfigured:
description: The authenticated Silicon has no active Hook destination.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: webhook_not_configured
message: Set the webhook url first.
request_id: 0199d8d5-2f62-7eb7-81c5-1e456778f8de
Error:
description: Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
OrgId:
type: string
pattern: ^[a-z0-9_-]{3,50}$
SiliconGlobalId:
type: string
pattern: ^[a-z0-9_-]{3,50}:[a-z0-9_-]{3,50}$
ScheduleStatus:
type: string
enum:
- active
- paused
- completed
ScheduleSection:
type: string
enum:
- current
- archived
MutableScheduleStatus:
type: string
enum:
- active
- paused
ScheduleStatusBatchUpdate:
type: object
required:
- schedule_ids
- status
additionalProperties: false
properties:
schedule_ids:
type: array
minItems: 1
maxItems: 100
uniqueItems: true
items:
type: string
format: uuid
status:
$ref: '#/components/schemas/MutableScheduleStatus'
ScheduleStatusBatchUpdateResponse:
type: object
required:
- items
additionalProperties: false
properties:
items:
type: array
minItems: 1
maxItems: 100
items:
$ref: '#/components/schemas/ScheduleStatusResult'
ScheduleStatusResult:
type: object
required:
- id
- status
- next_run_at
- updated_at
additionalProperties: false
properties:
id:
type: string
format: uuid
status:
$ref: '#/components/schemas/MutableScheduleStatus'
next_run_at:
type:
- string
- 'null'
format: date-time
updated_at:
type: string
format: date-time
ScheduleKind:
type: string
enum:
- one_time
- recurring
ScheduleCreate:
type: object
required:
- text
- kind
- cron
additionalProperties: false
properties:
text:
type: string
minLength: 1
maxLength: 100000
kind:
$ref: '#/components/schemas/ScheduleKind'
cron:
type: string
description: Five-field Linux cron expression
timezone:
type: string
default: UTC
description: IANA time-zone identifier
examples:
- Asia/Kolkata
Schedule:
allOf:
- $ref: '#/components/schemas/ScheduleCreate'
- type: object
required:
- id
- org_id
- silicon_id
- timezone
- status
- section
- next_run_at
- archived_at
- purge_after
- created_at
- updated_at
properties:
id:
type: string
format: uuid
org_id:
$ref: '#/components/schemas/OrgId'
silicon_id:
$ref: '#/components/schemas/SiliconGlobalId'
status:
$ref: '#/components/schemas/ScheduleStatus'
section:
$ref: '#/components/schemas/ScheduleSection'
next_run_at:
type:
- string
- 'null'
format: date-time
archived_at:
type:
- string
- 'null'
format: date-time
purge_after:
type:
- string
- 'null'
format: date-time
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
Execution:
type: object
required:
- id
- schedule_id
- scheduled_for
- status
properties:
id:
type: string
format: uuid
description: Stable idempotency identifier for this occurrence
schedule_id:
type: string
format: uuid
scheduled_for:
type: string
format: date-time
attempted_at:
type:
- string
- 'null'
format: date-time
delivered_at:
type:
- string
- 'null'
format: date-time
status:
type: string
enum:
- pending
- delivered
- retrying
- failed
hook_event_id:
type:
- string
- 'null'
format: uuid
failure_reason:
type:
- string
- 'null'
Error:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
- request_id
properties:
code:
type: string
message:
type: string
request_id:
type: string
Session:
type: object
properties:
access_token: *id009
refresh_token: *id009
expires_in:
type: integer
token_type: *id009
scope: *id009
actor:
type: object
org_id:
type:
- string
- 'null'
required:
- access_token
- refresh_token
- expires_in
- token_type
- scope
- actor
Identity:
type: object
properties:
principal_id: *id007
actor_type:
type: string
enum:
- carbon
- silicon
public_id:
type:
- string
- 'null'
org_id: *id009
membership_id: *id007
org_role:
type:
- string
- 'null'
authorization_epoch:
type: integer
minimum: 0
can_manage_reminders:
type: boolean
required:
- principal_id
- actor_type
- public_id
- org_id
- membership_id
- org_role
- authorization_epoch
- can_manage_reminders
DestinationInput:
type: object
properties:
endpoint_url:
type: string
format: uri
signing_secret: *id002
required:
- endpoint_url
- signing_secret
DestinationReceipt:
type: object
properties:
silicon_id: *id009
version: &id010
type: integer
updated_at: &id011
type: string
format: date-time
required:
- silicon_id
- version
- updated_at
DestinationInfo:
type: object
properties:
silicon_id: *id009
version: *id010
updated_at: *id011
endpoint_url:
type: string
format: uri
required:
- silicon_id
- version
- updated_at
- endpoint_url
Silicon:
type: object
properties:
principal_id: *id007
silicon_id: *id009
reminder_count:
type: integer
minimum: 0
required:
- principal_id
- silicon_id
- reminder_count
TestEnvironment:
type: object
properties:
id: *id007
org_id: *id009
creator_id: *id007
name: *id009
description:
type:
- string
- 'null'
iam_environment_id: *id007
version:
type: integer
created_at: *id011
last_activity_at: *id011
deleted_at: &id012
type:
- string
- 'null'
format: date-time
purge_after: *id012
required:
- id
- org_id
- creator_id
- name
- description
- iam_environment_id
- version
- created_at
- last_activity_at
- deleted_at
- purge_after
CreateTestEnvironment:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 100
description:
type:
- string
- 'null'
maxLength: 10000
iam_test_key:
type: string
pattern: ^[a-zA-Z0-9]{32}$
writeOnly: true
iam_app_secret: *id002
required:
- name
- iam_test_key
EnvironmentCreated:
type: object
properties:
environment:
$ref: '#/components/schemas/TestEnvironment'
key:
type: string
pattern: ^[a-zA-Z0-9]{32}$
required:
- environment
- key
EnvironmentKey:
type: object
properties:
environment_id: *id007
key:
type: string
pattern: ^[a-zA-Z0-9]{32}$
required:
- environment_id
- key
Health:
type: object
properties:
service: *id009
status: *id009
version: *id009
required:
- service
- status
- version