{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/api-evangelist/suprsend/refs/heads/main/json-schema/suprsend-schema.json", "title": "SuprSend API Schemas", "description": "JSON Schema definitions extracted from the SuprSend API OpenAPI specification.", "$defs": { "TemplateVariant": { "type": "object", "properties": { "$schema": { "type": "string", "description": "Schema URL for variant validation.", "example": "https://schema.suprsend.com/template/v2/variant_schema.json" }, "channel": { "type": "string", "description": "Channel this variant belongs to.", "example": "email" }, "id": { "type": "string", "description": "Variant identifier.", "example": "default" }, "tenant_id": { "type": "string", "nullable": true, "description": "Tenant this variant is scoped to, or null for default." }, "locale": { "type": "string", "description": "Locale code.", "example": "en" }, "conditions": { "type": "array", "description": "Conditions for variant selection at send time.", "items": { "type": "object" } }, "hash": { "type": "string", "description": "Content hash for change detection." }, "needs_vendor_approval": { "type": "boolean", "description": "Whether this variant requires vendor approval (SMS DLT, WhatsApp)." }, "sysgen_template_name": { "type": "string", "nullable": true, "description": "System-generated template name for vendor approval." }, "approval_status": { "type": "string", "enum": [ "auto_approved", "pending", "sent_for_approval", "approved", "rejected" ], "description": "Current approval status of the variant." }, "discard_comment": { "type": "string", "nullable": true, "description": "Reason provided when a variant is discarded." }, "approval_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Timestamp when the variant was approved." }, "has_error": { "type": "boolean", "description": "Whether the variant has validation errors." }, "seq_no": { "type": "integer", "description": "Ordering within the channel + tenant + locale combination." }, "action": { "type": "string", "nullable": true, "description": "Action taken in the latest commit (Updated, Added, Unchanged, or null)." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the variant was created." }, "content": { "type": "object", "description": "Channel-specific content. Structure varies by channel. Only returned in variant detail endpoint." }, "vendor_approvals": { "type": "array", "description": "Vendor approval entries (WhatsApp/SMS only). Only returned in variant detail endpoint.", "items": { "type": "object" } } } }, "Workflow": { "type": "object", "properties": { "$schema": { "type": "string", "format": "uri", "description": "Schema URL for workflow validation", "example": "https://schema.suprsend.com/workflow/v1/schema.json" }, "slug": { "type": "string", "description": "Unique identifier for the workflow", "minLength": 1, "maxLength": 255, "pattern": "^[a-z0-9-_]+$", "example": "welcome-sequence" }, "is_enabled": { "type": "boolean", "description": "Whether the workflow is enabled", "example": true }, "created_at": { "type": "string", "format": "date-time", "description": "When the workflow was created" }, "last_executed_at": { "type": "string", "format": "date-time", "description": "When the workflow was last executed", "nullable": true }, "name": { "type": "string", "description": "Human-readable name of the workflow", "example": "Welcome Sequence" }, "description": { "type": "string", "nullable": true, "description": "Description explaining the usecase of the workflow" }, "updated_at": { "type": "string", "format": "date-time", "description": "When the workflow was last updated" }, "commit_message": { "type": "string", "nullable": true, "description": "Last commit message" }, "hash": { "type": "string", "nullable": true, "description": "Git-like hash for version tracking" }, "status": { "type": "string", "enum": [ "active", "inactive", "draft" ], "description": "Current status of the workflow" }, "category": { "type": "string", "description": "Notification category of the workflow. Used to apply category-specific settings and preferences.", "example": "transactional" }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Tags for organizing and filtering workflows in API." }, "ratelimit": { "type": "object", "nullable": true, "description": "Workflow [throttle](https://docs.suprsend.com/docs/throttle) settings. This is used to limit the number of times a workflow can be executed per user in a given time period." }, "conditions": { "type": "array", "items": { "type": "object" }, "description": "Trigger Conditions for workflow execution. Workflow will only be executed if trigger conditions evaluate to true." }, "trigger_type": { "type": "string", "enum": [ "event", "dynamic", "api" ], "description": "How the workflow is triggered. You can refer to all trigger types [here](https://docs.suprsend.com/reference/trigger-workflows#trigger-types)." }, "trigger_events": { "type": "array", "items": { "type": "string" }, "description": "Events that trigger this workflow. This will be set for trigger_type = `event`." }, "override_recipients_type": { "type": "string", "nullable": true, "description": "Type of recipient override. Define whether to override and run this workflow for user, list of users or a single object.", "enum": [ "user", "single_object_fields" ] }, "override_recipients_user_expr": { "type": "string", "nullable": true, "description": "Expression for overriding recipients when override_recipients_type = `user`." }, "override_recipients_single_object_fields_expr": { "type": "string", "nullable": true, "description": "Expression for overriding recipients when override_recipients_type = `single_object_fields`." }, "override_actor_user_expr": { "type": "string", "nullable": true, "description": "Expression for overriding actor" }, "override_tenant_expr": { "type": "string", "nullable": true, "description": "Expression for overriding tenant" }, "active_at": { "type": "string", "format": "date-time", "description": "When the workflow's live version became active. Will be `null` for draft version." }, "updated_by": { "type": "object", "nullable": true, "properties": { "name": { "type": "string", "description": "Name of the user who last updated the workflow" }, "email": { "type": "string", "format": "email", "description": "Email of the user who last updated the workflow" } }, "description": "User who last updated the workflow" }, "tree": { "type": "object", "description": "Node tree structure of the workflow. Shows the list of all nodes used in the workflow along with their configuration." }, "validation_result": { "type": "object", "properties": { "is_valid": { "type": "boolean", "description": "true if the workflow tree is valid to be published." }, "errors": { "type": "array", "items": { "type": "string" }, "description": "List of errors if the workflow tree is not valid." } }, "description": "Validation status of the workflow" } } }, "WorkflowTriggerSingleBody": { "type": "object", "description": "A single workflow trigger payload. Send this object as-is for a single workflow trigger, or wrap multiple instances in a JSON array for a bulk trigger.", "required": [ "workflow", "recipients" ], "properties": { "workflow": { "type": "string", "description": "You can get workflow slug from workflow settings on SuprSend dashboard.", "default": "_workflow_slug_" }, "recipients": { "type": "array", "description": "List of recipients to be notified. You can either add recipient as array of distinct_ids or array of recipient objects. You can add up to 100 recipients in a single API.", "items": { "oneOf": [ { "type": "object", "title": "Identify user inline", "description": "You can pass user properties and channels inline in workflow trigger request. Properties and channels passed here also update in user profile on workflow trigger.", "required": [ "distinct_id" ], "properties": { "is_transient": { "type": "boolean", "description": "set `is_transient = true` to send notification to anonymous user. You don't need to pass `distinct_id` for anonymous sending." }, "distinct_id": { "type": "string", "description": "unique identifier of the user who needs to be notified", "default": "id1" }, "$channels": { "type": "array", "items": { "type": "string", "example": "email", "description": "channel to send notification to", "enum": [ "email", "sms", "inbox", "androidpush", "iospush", "slack", "ms_teams", "webpush", "whatsapp" ] } }, "$email": { "type": "array", "items": { "type": "string", "format": "email", "example": "john@example.com" } }, "$sms": { "type": "array", "items": { "type": "string", "example": "+1234567890" } }, "$inbox": { "type": "array", "items": { "type": "string", "example": "4nlPk4t4kurG5kChxxxx" } }, "$androidpush": { "type": "array", "items": { "type": "string", "example": "__android_push_token__" } }, "$iospush": { "type": "array", "items": { "type": "string", "example": "__ios_push_token__" } }, "$slack": { "type": "array", "description": "Slack channel configuration", "items": { "oneOf": [ { "type": "object", "title": "Slack using email", "required": [ "email", "access_token" ], "properties": { "email": { "type": "string", "format": "email", "description": "User email address", "example": "user@example.com" }, "access_token": { "type": "string", "description": "Slack bot access token", "example": "xoxb-XXXXXXXX" } } }, { "type": "object", "title": "Slack using member ID", "required": [ "user_id", "access_token" ], "properties": { "user_id": { "type": "string", "description": "Slack user ID (U/WXXXXXXXX format)", "example": "U/WXXXXXXXX" }, "access_token": { "type": "string", "description": "Slack bot access token", "example": "xoxb-XXXXXX" } } }, { "type": "object", "title": "Slack using channel", "required": [ "channel", "access_token" ], "properties": { "channel": { "type": "string", "description": "Slack channel ID (CXXXXXXXX format)", "example": "CXXXXXXXX" }, "access_token": { "type": "string", "description": "Slack bot access token", "example": "xoxb-XXXXXX" } } }, { "type": "object", "title": "Slack using incoming webhook", "required": [ "incoming_webhook" ], "properties": { "incoming_webhook": { "type": "object", "required": [ "url" ], "properties": { "url": { "type": "string", "format": "uri", "description": "Slack incoming webhook URL", "example": "https://hooks.slack.com/services/TXXXX/BXXXX/XXXXXXX" } } } } } ] } }, "$ms_teams": { "type": "array", "description": "Microsoft Teams channel configuration", "items": { "oneOf": [ { "type": "object", "title": "MS Teams using conversation ID", "required": [ "tenant_id", "service_url", "conversation_id" ], "properties": { "tenant_id": { "type": "string", "description": "Microsoft Teams tenant ID", "example": "c1981ab2-9aaf-xxxx-xxxx" }, "service_url": { "type": "string", "format": "uri", "description": "Microsoft Teams service URL", "example": "https://smba.trafficmanager.net/amer" }, "conversation_id": { "type": "string", "description": "Microsoft Teams conversation ID", "example": "19:c1524d7c-a06f-456f-8abe-xxxx" } } }, { "type": "object", "title": "MS Teams using user ID", "required": [ "tenant_id", "service_url", "user_id" ], "properties": { "tenant_id": { "type": "string", "description": "Microsoft Teams tenant ID", "example": "c1981ab2-9aaf-xxxx-xxxx" }, "service_url": { "type": "string", "format": "uri", "description": "Microsoft Teams service URL", "example": "https://smba.trafficmanager.net/amer" }, "user_id": { "type": "string", "description": "Microsoft Teams user ID", "example": "29:1nsLcmJ2RKtYH6Cxxxx-xxxx" } } }, { "type": "object", "title": "MS Teams using incoming webhook", "required": [ "incoming_webhook" ], "properties": { "incoming_webhook": { "type": "object", "required": [ "url" ], "properties": { "url": { "type": "string", "format": "uri", "description": "Microsoft Teams incoming webhook URL", "example": "https://wnk1z.webhook.office.com/webhookb2/XXXXXXXXX" } } } } } ] } }, "$timezone": { "type": "string", "example": "America/New_York" }, "$locale": { "type": "string", "example": "en_GB" } } }, { "type": "object", "title": "Notify object", "required": [ "id", "object_type" ], "properties": { "id": { "type": "string", "description": "Unique identifier of the object", "example": "frontend" }, "object_type": { "type": "string", "description": "Filename to be shown in email" } }, "additionalProperties": { "type": "string", "description": "You can pass other user properties similar to recipient payload. It will be used when notification is sent to object channels as $recipient.." } } ] } }, "actor": { "type": "object", "description": "Includes distinct_id and properties of the user who performed the action. You can use it for [cross-user notifications](\"https://docs.suprsend.com/docs/trigger-workflow#sending-cross-user-notifications\"). Actor properties can be added as `$actor.`.", "properties": { "is_transient": { "type": "boolean", "description": "set `is_transient = true` to pass anonymous actor. You don't need to pass `distinct_id` for anonymous user." }, "distinct_id": { "type": "string", "description": "unique identifier of the actor who performed the action", "default": "id1" } }, "additionalProperties": { "type": "string", "description": "You can pass additional actor properties as `\"user_prop1\":\"value1\"` . Extra properties will be update in user profile which can then be used in the template as `$actor.`." } }, "data": { "type": "object", "description": "variable data required to render dynamic template content or workflow properties like dynamic delay or channel override in send node.", "properties": { "$attachments": { "type": "array", "description": "Use this key to pass email attachment in the trigger. You can either pass attachment as a public URL or as a base64-encoded file (limit < 50KB).", "items": { "oneOf": [ { "type": "object", "title": "Pass Public URL", "description": "Pass file as **publicly accessible URL** (No limit on file size)", "required": [ "url" ], "properties": { "url": { "type": "string", "format": "uri", "description": "Publicly accessible URL of the file", "example": "https://bitcoincore.org/bitcoin.pdf" }, "filename": { "type": "string", "description": "Filename to be shown in email", "example": "billing.pdf" }, "ignore_if_error": { "type": "boolean", "description": "Ignore the attachment if it fails to load" } } }, { "type": "object", "title": "Pass Base64 File Locally", "description": "Pass file as a **base-64 file** (supported limit < 50KB)", "required": [ "data" ], "properties": { "data": { "type": "string", "description": "Base64-encoded content of the file" }, "filename": { "type": "string", "description": "Filename to be shown in email" }, "contentType": { "type": "string", "example": "application/pdf" } } } ] } } }, "additionalProperties": { "type": "string" } }, "tenant_id": { "type": "string", "description": "string identifier of the tenant/tenant this workflow is associated with. Used to trigger [multi-tenant](https://docs.suprsend.com/docs/tenant-workflows) notifications" }, "$idempotency_key": { "type": "string", "description": "Idempotency_key (valid for 24hrs)" } } }, "DigestNode": { "type": "object", "description": "[**Digest**](https://docs.suprsend.com/docs/digest): Batches and sends summary notifications at a recurring digest schedule.", "required": [ "node_type", "name", "schedule_type" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Daily digest" }, "node_type": { "type": "string", "const": "digest" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "schedule_type": { "type": "string", "enum": [ "static", "dynamic" ], "description": "Type of schedule. Determines if the schedule is static or dynamic. \n\n**static**: Schedule is fixed and will be used for all recipients. \n\n**dynamic**: Schedule is dynamic and will be computed at runtime using the `dynamic_schedule_expr`." }, "dynamic_schedule_expr": { "type": "string", "description": "jq-expression for deriving dynamic digest schedule at runtime. Eg. `.digest_schedule`", "example": ".digest_schedule" }, "schedule": { "$ref": "#/components/schemas/Schedule" }, "retain_count": { "type": "integer", "minimum": 1, "maximum": 100, "description": "Maximum number of items to retain after digest closes (1-100). By default, 10 items are retained." }, "retain_order": { "type": "string", "enum": [ "first", "last" ], "description": "Retain items in this order when retain_count is specified." }, "trigger_min_count": { "type": "integer", "minimum": 1, "description": "Digest will be sent if number of triggers in the batch are greater than or equal to this count, else skipped." } } }, "Schedule": { "type": "object", "description": "Static schedule configuration for digest notifications.", "properties": { "frequency": { "type": "string", "enum": [ "minutely", "hourly", "daily", "weekly_mo2fr", "weekly", "monthly" ], "description": "Frequency of the digest schedule." }, "interval": { "type": "integer", "minimum": 1, "description": "Multiplier for recurrence schedule. Eg. 2 for every 2 hours, 3 for every 3 days, etc." }, "weekdays": { "type": "array", "items": { "type": "string", "enum": [ "su", "mo", "tu", "we", "th", "fr", "sa" ] }, "description": "Which days to include when frequency is 'weekly'." }, "monthdays": { "type": "array", "items": { "type": "object", "properties": { "pos": { "type": "integer", "minimum": -31, "maximum": 31 }, "day": { "type": "string", "enum": [ null, "su", "mo", "tu", "we", "th", "fr", "sa" ] } } }, "description": "Which days to include when frequency is 'monthly'." }, "time": { "type": "string", "description": "Time of day to send digest in HH:MM format (24-hour).", "examples": [ "09:00", "18:30" ] }, "dtstart": { "type": "string", "description": "When to start schedule calculation from in ISO datetime format." }, "tz_selection": { "type": "string", "enum": [ "fixed", "recipient" ], "description": "timezone of the recurring schedule. \n\n**fixed**: Fixed timezone. \n\n**recipient**: Recipient's timezone picked from user properties." }, "tz_fixed": { "type": "string", "description": "Fixed IANA timezone.", "pattern": "^[A-Za-z_/]+$", "examples": { "new_york": { "summary": "New York timezone", "value": "America/New_York" }, "london": { "summary": "London timezone", "value": "Europe/London" } } } } }, "DelayNode": { "type": "object", "description": "[**Delay**](https://docs.suprsend.com/docs/delay): Pauses workflow execution for a specified duration.", "required": [ "node_type", "name", "delay_type" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Wait 30 minutes" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "node_type": { "type": "string", "const": "delay" }, "delay_type": { "type": "string", "enum": [ "fixed", "dynamic", "relative_to" ], "description": "Type of delay. Determines how the duration is calculated. \n\n**Fixed**: Static duration added as XXdXXhXXmXXs.\n\n **Dynamic**: duration is passed as variable in your trigger payload in jq format. Eg. `.delay_duration`, `$recipient.delay_duration`, `$actor.delay_duration`, `$tenant.delay_duration`.\n\n **Relative to**: delay is relative to a future timestamp passed in your trigger payload. Eg. `.start_time` before 15m." }, "duration": { "type": "string", "description": "Duration value. Required for 'fixed' and 'dynamic' delay types.", "examples": { "fixed_duration": { "summary": "Fixed duration example", "value": "30s" }, "dynamic_duration": { "summary": "Dynamic duration from trigger payload", "value": ".delay_duration" }, "recipient_duration": { "summary": "Dynamic duration from recipient properties", "value": "$recipient.delay_duration" } } }, "relative_to": { "type": "object", "description": "Relative delay configuration. Required when delay_type is 'relative_to'.", "properties": { "pivot_expr": { "type": "string", "description": "(jq-expression) variable defining the future timestamp from trigger payload relative to which delay is calculated.", "example": ".start_time" }, "offset_type": { "type": "string", "enum": [ "before", "after" ], "description": "Whether offset is to be added or subtracted from pivot_expr." }, "offset_value_type": { "type": "string", "enum": [ "fixed", "dynamic" ], "description": "Defines if the offset value is fixed or dynamic. \n\n**Fixed**: Static duration added as XXdXXhXXmXXs. Eg. 15m before meeting_start_time. \n\n**Dynamic**: offset is passed as variable in your trigger payload or recipient, tenant properties in jq format. Eg. `$recipient.reminder_offset` before meeting_start_time." }, "offset_value": { "type": "string", "description": "Offset value", "examples": { "fixed_offset": { "summary": "Fixed duration offset", "value": "15m" }, "dynamic_offset": { "summary": "Dynamic offset from recipient properties", "value": "$recipient.reminder_offset" } } } } } } }, "BatchNode": { "type": "object", "description": "[**Batch**](https://docs.suprsend.com/docs/batch): Batches incoming workflow triggers/events for a duration to send consolidated notifications.", "required": [ "node_type", "name", "mode", "window_type" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Batch notifications" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "node_type": { "type": "string", "const": "batch" }, "mode": { "type": "string", "enum": [ "accumulate_all", "flush_leading_item" ], "description": "**accumulate_all**: All events are accumulated in the batch and notification is sent once after batch window closes. \n\n**flush_leading_item**: Notification is sent immediately for the first event in the batch and rest of the events are batched and sent after batch window closes. Eg. Send anomaly alert with first notification sent at the occurrence of first error and next alert sent after 30 minutes if there are further errors." }, "window_type": { "type": "string", "enum": [ "fixed", "dynamic", "relative_to" ], "description": "Type of batching window. \n\n**fixed**: Static window duration added as XXdXXhXXmXXs. Eg. 30s, 1h, 1d. \n\n**dynamic**: Batch window duration is passed as variable in your trigger payload. Add the variable in jq format. Eg. `.window_duration`, `$recipient.batch_duration`, `$actor.window_duration`, `$tenant.window_duration`. \n\n**relative_to**: Batch window is relative to a future timestamp passed in your trigger payload. Eg. 15 m before `.task_end_time`." }, "fixed_window": { "type": "string", "description": "Batch window when window_type is 'fixed'. Static batch window for all users. Format: XXdXXhXXmXXs.", "example": "30s" }, "dynamic_window_expr": { "type": "string", "description": "Batch window when window_type is 'dynamic'. jq-expression for deriving batch window duration at runtime.", "examples": { "trigger_payload": { "summary": "From trigger payload", "value": ".window_duration" }, "recipient_property": { "summary": "From recipient properties", "value": "$recipient.batch_duration" }, "actor_property": { "summary": "From actor properties", "value": "$actor.window_duration" }, "tenant_property": { "summary": "From tenant properties", "value": "$tenant.window_duration" } } }, "relative_to": { "type": "object", "description": "Batch window when window_type is 'relative_to'. Batch window is calculated relative to a future timestamp.", "properties": { "pivot_expr": { "type": "string", "description": "(jq-expression) variable defining the future timestamp from trigger payload relative to which batch window is calculated.", "examples": { "trigger_payload": { "summary": "From trigger payload", "value": ".start_time" }, "recipient_property": { "summary": "From recipient properties", "value": "$recipient.task_end_time" } } }, "offset_type": { "type": "string", "enum": [ "before", "after" ], "description": "Whether offset is to be added or subtracted from pivot timestamp." }, "offset_value_type": { "type": "string", "enum": [ "fixed", "dynamic" ], "description": "Defines if the offset value is fixed or dynamic. \n\n**Fixed**: Static duration added as XXdXXhXXmXXs. Eg. 15m before meeting_start_time. \n\n**Dynamic**: offset is passed as variable in your trigger payload or recipient, tenant properties in jq format. Eg. `$recipient.reminder_offset` before meeting_start_time." }, "offset_value": { "type": "string", "description": "Offset value.", "examples": { "fixed_offset": { "summary": "Fixed duration offset", "value": "15m" }, "dynamic_offset": { "summary": "Dynamic offset from recipient properties", "value": "$recipient.reminder_offset" } } } } }, "retain_count": { "type": "integer", "minimum": 1, "maximum": 100, "description": "Maximum number of items to retain after batch closes (1-100). The output variable set will have the latest or first n items based on the retain_order." }, "retain_order": { "type": "string", "enum": [ "first", "last" ], "description": "Retain items in this order when retain_count is specified." }, "batch_key": { "type": "string", "description": "jq-expression used to group events into separate batches. For example, when sending batched notifications for comments on different documents, use `.document_id` as the batch key to ensure comments from different documents are not combined into the same batch.", "example": ".document_id" } } }, "HttpApiWebhookNode": { "type": "object", "description": "[**Webhook**](https://docs.suprsend.com/docs/webhook): Makes an HTTP API request to an endpoint.", "required": [ "node_type", "name", "http_method", "url" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Notify internal CRM" }, "node_type": { "type": "string", "const": "httpapi_webhook" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "http_method": { "type": "string", "enum": [ "GET", "PUT", "POST", "PATCH", "DELETE" ], "description": "HTTP method of the API call." }, "url": { "type": "string", "format": "uri", "description": "Endpoint URL of the API call. You can add variables in JSONNET format. Eg. `\"https://api.example.com/webhook?id=\"+data[\"$recipient\"].id`", "example": "https://api.example.com/webhook" }, "headers": { "type": "array", "description": "List of headers as key-value pairs. You can add variables in JSONNET format. Eg. `\"Bearer\"+data[\"$tenant\"].api_key`", "items": { "type": "object", "properties": { "key": { "type": "string", "description": "header key", "example": [ "\"Authorization\"", "\"Content-Type\"" ] }, "value": { "type": "string", "description": "header value", "example": [ "\"Bearer \"+data[\"$tenant\"].api_key", "\"application/json\"" ] } } } }, "body_content_type": { "type": "string", "default": "application/json", "description": "Content type for the body." }, "body": { "type": "string", "description": "JSONNET script to evaluate request body." }, "query_params": { "type": "array", "description": "List of query parameters as key-value pairs. You can add variables in JSONNET format. Eg. `data[\"$recipient\"].id`", "items": { "type": "object", "properties": { "key": { "type": "string", "description": "Query Parameter Key" }, "value": { "type": "string", "description": "Query Parameter Value" } } } }, "output_key": { "type": "string", "description": "Optional key to store the response body of API call. If not provided, the response will be appended at the root of the workflow payload. It's recommended to provide a unique key here to avoid overwriting existing data." } } }, "HttpApiFetchNode": { "type": "object", "description": "[**Fetch**](https://docs.suprsend.com/docs/fetch): Fetches data from an API endpoint using GET method only.", "required": [ "node_type", "name", "http_method", "url" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Fetch user data" }, "node_type": { "type": "string", "const": "httpapi_fetch" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "http_method": { "type": "string", "const": "GET", "description": "HTTP method to use. Only GET is supported for fetch operations." }, "url": { "type": "string", "description": "Endpoint URL to fetch data from.", "example": "https://api.example.com/data" }, "headers": { "type": "array", "description": "List of headers as key-value pairs. You can add variables in JSONNET format. Eg. `\"Bearer\"+data[\"$tenant\"].api_key`", "items": { "type": "object", "properties": { "key": { "type": "string", "description": "header key", "examples": { "authorization": { "summary": "Authorization header", "value": "\"Authorization\"" }, "content_type": { "summary": "Content-Type header", "value": "Content-Type" } } }, "value": { "type": "string", "description": "header value", "example": [ "\"Bearer \"+data[\"$tenant\"].api_key", "\"application/json\"" ] } } } }, "query_params": { "type": "array", "description": "List of query parameters as key-value pairs. You can add variables in JSONNET format. Eg. `data[\"$recipient\"].id`", "items": { "type": "object", "properties": { "key": { "type": "string", "description": "Query Parameter Key", "examples": { "id_param": { "summary": "ID parameter", "value": "id" }, "name_param": { "summary": "Name parameter", "value": "name" } } }, "value": { "type": "string", "description": "Query Parameter Value", "examples": { "data_id": { "summary": "Data ID from payload", "value": "data.id" }, "recipient_name": { "summary": "Recipient name from data", "value": "data[\"$recipient\"].name" } } } } } }, "output_key": { "type": "string", "description": "Optional key to store the response of API call. If not provided, the response will be appended at the root of the workflow payload. It's recommended to provide a unique key here to avoid overwriting existing data." } } }, "BranchWaitUntilNode": { "type": "object", "description": "[**Wait Until**](https://docs.suprsend.com/docs/wait-until): Waits until a condition is met or the maximum time is reached. Uses branch structure with conditions.", "required": [ "node_type", "name", "branches" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Wait for approval" }, "node_type": { "type": "string", "const": "branch_waituntil" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "branches": { "type": "array", "description": "Array of branches with conditions to evaluate. Minimum 2 branches required.", "minItems": 2, "maxItems": 2, "items": { "type": "object", "properties": { "name": { "type": "string", "description": "Name of the branch for identification." }, "description": { "type": "string", "description": "Description of what this branch does." }, "is_default": { "type": "boolean", "description": "Whether this is the default branch. In case of wait until, branch with condition->type as 'delay' (max time) should always be the default branch." }, "conditions": { "type": "array", "description": "Array of conditions to evaluate for this branch.", "items": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "future_event", "delay" ], "description": "Type of condition to evaluate." }, "event_name": { "type": "string", "description": "Name of the future event to wait for. Eg. `\"request_approved\"`", "maxLength": 255 }, "event_conditions": { "type": "array", "description": "Additional conditions to evaluate when the future event occurs.", "items": { "type": "object", "properties": { "variable_ns": { "type": "string", "description": "Namespace for the variable on left-hand side of expression.", "allowed_values": [ { "": "Default namespace (payload data)" }, { "$brand": "tenant/brand properties" }, { "$actor": "user properties of the actor" }, { "$recipient": "user properties of the recipient" }, { "$future_event": "Future event properties" } ], "required": false }, "variable": { "type": "string", "description": "Variable name on left-hand side of expression.", "required": true, "example": "status" }, "op": { "type": "string", "description": "Comparison operator for the expression.", "allowed_values": [ { "==": "Equal to" }, { "!=": "Not equal to" }, { ">": "Greater than" }, { "<": "Less than" }, { ">=": "Greater than or equal to" }, { "<=": "Less than or equal to" }, { "EMPTY": "Empty" }, { "NON_EMPTY": "Not empty" }, { "CONTAINS": "Contains" }, { "NOT_CONTAINS": "Does not contain" }, { "DATETIME_EQUALS": "Date time equals" }, { "DATETIME_LT": "Date time less than" }, { "DATETIME_GT": "Date time greater than" } ] }, "value": { "type": "string", "description": "Right-hand side operand.", "example": "approved" } } } }, "delay_properties": { "type": "object", "description": "Timeout value after which the branch will be executed. Required when condition->type is 'delay'.", "properties": { "delay_type": { "type": "string", "enum": [ "fixed", "dynamic", "relative_to" ], "description": "Type of delay calculation. \n\n**fixed**: Static duration added as XXdXXhXXmXXs. \n\n**dynamic**: duration is passed as variable in your trigger payload in jq format. Eg. `.delay_duration`, `$recipient.delay_duration`, `$actor.delay_duration`, `$tenant.delay_duration`. \n\n**relative_to**: delay is relative to a future timestamp passed in your trigger payload. Eg. `.start_time` before 15m." }, "value": { "type": "string", "description": "Delay value. Required for 'fixed' and 'dynamic' delay types.", "examples": { "fixed_duration": { "summary": "Fixed duration example", "value": "30s" }, "dynamic_duration": { "summary": "Dynamic duration from trigger payload", "value": ".delay_duration" }, "recipient_duration": { "summary": "Dynamic duration from recipient properties", "value": "$recipient.delay_duration" } } }, "relative_to": { "type": "object", "description": "Relative delay configuration. Required when delay_type is 'relative_to'.", "example": { "pivot_expr": ".start_time", "offset_type": "before", "offset_value_type": "fixed", "offset_value": "15m" }, "properties": { "pivot_expr": { "type": "string", "description": "(jq-expression) variable defining the future timestamp from trigger payload relative to which delay is calculated." }, "offset_type": { "type": "string", "enum": [ "before", "after" ], "description": "Whether to add or subtract offset from pivot." }, "offset_value_type": { "type": "string", "enum": [ "fixed", "dynamic" ], "description": "How to determine offset value. \n\n**fixed**: Static duration added as XXdXXhXXmXXs. Eg. 15m before meeting_start_time. \n\n**dynamic**: offset is passed as variable in your trigger payload or recipient, tenant properties in jq format. Eg. `$recipient.reminder_offset` before meeting_start_time." }, "offset_value": { "type": "string", "description": "Offset value. Required for 'fixed' and 'dynamic' offset_value_types.", "examples": { "fixed_offset": { "summary": "Fixed duration offset", "value": "15m" }, "dynamic_offset": { "summary": "Dynamic offset from recipient properties", "value": "$recipient.reminder_offset" } } } } } } } } } }, "nodes": { "type": "array", "description": "Array of nodes to execute when this branch condition is met. Minimum 1 node required." } } } } } }, "BranchNode": { "type": "object", "description": "[**Branch**](https://docs.suprsend.com/docs/branch): Divides the workflow in different branches and executes the first branch that matches the branch condition.", "required": [ "node_type", "name", "branches" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Check user type" }, "node_type": { "type": "string", "const": "branch" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "branches": { "type": "array", "description": "Array of branches with conditions to evaluate. Minimum 2 branches required.", "minItems": 2, "maxItems": 10, "items": { "type": "object", "properties": { "name": { "type": "string", "description": "Name of the branch for identification." }, "description": { "type": "string", "description": "Description of what this branch does." }, "is_default": { "type": "boolean", "description": "Whether this is the default branch. Default branch is executed if no other branch conditions are met." }, "conditions": { "type": "array", "description": "Array of conditions to evaluate for this branch.", "items": { "type": "object", "properties": { "type": { "type": "string", "const": "expression_v1", "description": "Type of condition to evaluate. Only expression_v1 is supported for regular branch nodes." }, "expression_v1": { "type": "object", "description": "Boolean expression evaluation structure.", "properties": { "op": { "type": "string", "enum": [ "AND", "OR" ], "description": "Logical operator for combining conditions." }, "args": { "type": "array", "description": "Array of individual condition expressions or nested logical expressions.", "items": { "type": "object", "properties": { "variable_ns": { "type": "string", "description": "Namespace for the variable on left-hand side of expression. Allowed values: \"\" (Default namespace - payload data), \"$brand\" (tenant/brand properties), \"$actor\" (user properties of the actor), \"$recipient\" (user properties of the recipient), \"$future_event\" (Future event properties), \"$workflow\" (Workflow properties).", "required": false, "enum": [ "", "$brand", "$actor", "$recipient", "$future_event", "$workflow" ] }, "variable": { "type": "string", "description": "Variable name on left-hand side of expression." }, "op": { "type": "string", "enum": [ "==", "!=", ">", ">=", "<", "<=", "EMPTY", "NON_EMPTY", "CONTAINS", "NOT_CONTAINS", "DATETIME_EQUALS", "DATETIME_LT", "DATETIME_GT" ], "description": "Comparison operator for the expression." }, "value": { "type": "string", "description": "Right-hand side operand." }, "args": { "type": "array", "description": "Array of conditions for nested logical expressions." } } } } } } } } }, "nodes": { "type": "array", "description": "Array of nodes to execute when this branch condition is met." } } } } } }, "TransformNode": { "type": "object", "description": "[**Data Transform**](https://docs.suprsend.com/docs/data-transform): Transforms data or generates/overrides variables using scripting languages like JSONNET or Handlebars.", "required": [ "node_type", "name", "variables" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Transform data" }, "node_type": { "type": "string", "const": "transform" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "variables": { "type": "array", "description": "Array of variables to generate or override. Each variable must have a unique key.", "minItems": 1, "items": { "type": "object", "properties": { "key": { "type": "string", "description": "Literal string key for the variable.", "minLength": 1 }, "value_lang": { "type": "string", "enum": [ "jsonnet", "handlebars" ], "description": "Scripting language to use for deriving the variable value at runtime." }, "value": { "type": "string", "description": "Script in the selected language to derive the value of the variable at runtime.", "minLength": 1 } } } } } }, "TimeWindowNode": { "type": "object", "description": "[**Time Window**](https://docs.suprsend.com/docs/time-window): Restricts workflow execution to specific time windows based on recurrence rules.", "required": [ "node_type", "name", "windows" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Business hours only" }, "node_type": { "type": "string", "const": "timewindow" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "windows": { "type": "array", "description": "Array of time windows defined using recurrence rule structure.", "minItems": 1, "items": { "type": "object", "properties": { "frequency": { "type": "string", "enum": [ "daily", "weekly_mo2fr", "weekly", "monthly" ], "description": "Frequency of the time window recurrence." }, "weekdays": { "type": "array", "description": "Which days to include when frequency is 'weekly'.", "items": { "type": "string", "enum": [ "su", "mo", "tu", "we", "th", "fr", "sa" ] } }, "monthdays": { "type": "array", "description": "Which days to include when frequency is 'monthly'.", "items": { "type": "object", "properties": { "pos": { "type": "integer", "minimum": -31, "maximum": 31, "description": "Day number (-31 to 31)." }, "day": { "type": "string", "enum": [ null, "su", "mo", "tu", "we", "th", "fr", "sa" ], "description": "Weekday when specifying nth weekday of month. Negative values indicate the nth last occurrence of the weekday in the month." } } } }, "stime": { "type": "string", "description": "Clock start time of the window in HH:MM format (24-hour).", "example": "08:00" }, "etime": { "type": "string", "description": "Clock end time of the window in HH:MM format (24-hour).", "example": "17:00" } } } }, "tz_selection": { "type": "string", "enum": [ "fixed", "recipient" ], "description": "Where to pick timezone from for calculating datetime from recurrence rule. \n\n**fixed**: Use a fixed timezone. \n\n**recipient**: Use the timezone set in recipient properties." }, "tz_fixed": { "type": "string", "description": "Fixed IANA timezone for calculating datetime in recurrence rule.", "example": "America/New_York" } } }, "SubscriberListOperationAddUserNode": { "type": "object", "description": "[**Add User to List**](https://docs.suprsend.com/docs/add-user-to-list): Adds users (actor or recipient) to a subscriber list. Can create the list if it doesn't exist.", "required": [ "node_type", "name", "list_id", "user_selection" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Add to newsletter list" }, "node_type": { "type": "string", "const": "subscriberlistoperation_adduser" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "is_list_id_dynamic": { "type": "boolean", "default": false, "description": "Whether list_id is a static literal string or a handlebars expression." }, "list_id": { "type": "string", "description": "List identifier. Can be a static literal string or a handlebars expression added as {{list_id}}.", "minLength": 1 }, "create_list_if_missing": { "type": "boolean", "default": false, "description": "Whether to create the list if it doesn't exist." }, "list_name": { "type": "string", "description": "Name for the list when creating it. Pass when `create_list_if_missing` is true.", "minLength": 1 }, "user_selection": { "type": "array", "description": "Which users to add to the list. Can select actor, recipient, or both.", "minItems": 1, "items": { "type": "string", "enum": [ "actor", "recipient" ] } } } }, "SubscriberListOperationRemoveUserNode": { "type": "object", "description": "[**Remove User from List**](https://docs.suprsend.com/docs/remove-user-from-list): Removes users (actor or recipient) from the list. List must exist for the operation to succeed.", "required": [ "node_type", "name", "list_id", "user_selection" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Remove from newsletter list" }, "node_type": { "type": "string", "const": "subscriberlistoperation_removeuser" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "is_list_id_dynamic": { "type": "boolean", "default": false, "description": "Whether list_id is a static literal string or a handlebars expression." }, "list_id": { "type": "string", "description": "List identifier. Can be a static literal string or a handlebars expression (to compute the list id at runtime. Eg. {{list_id}}).", "minLength": 1 }, "user_selection": { "type": "array", "description": "Which users to remove from the list. Can select actor, recipient, or both.", "minItems": 1, "items": { "type": "string", "enum": [ "actor", "recipient" ] } } } }, "ObjectOperationAddSubscriptionNode": { "type": "object", "description": "[**Subscribe to Object**](https://docs.suprsend.com/docs/subscribe-to-object): Adds users (actor or recipient) as subscribers to an object. Can create the object if it doesn't exist.", "required": [ "node_type", "name", "object_type", "object_id", "user_selection" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Add use to team object" }, "node_type": { "type": "string", "const": "objectoperation_addsubscription" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "is_object_id_dynamic": { "type": "boolean", "default": false, "description": "Whether object_type and object_id are static literal strings or handlebars expressions." }, "object_type": { "type": "string", "description": "Type/collection name of the object.", "minLength": 1 }, "object_id": { "type": "string", "description": "Unique identifier of the object within the object_type.", "minLength": 1 }, "create_object_if_missing": { "type": "boolean", "description": "Whether to create the object if it doesn't exist." }, "user_selection": { "type": "array", "description": "Which users to add as subscribers to the object. Can select actor, recipient, or both.", "minItems": 1, "items": { "type": "string", "enum": [ "actor", "recipient" ] } }, "subscription_properties": { "type": "string", "description": "Additional subscription properties which defines the relationship between object and user. Eg. role, designation, etc. Pass as JSONNET expression.", "example": "{\"role\": \"admin\"}" } } }, "ObjectOperationRemoveSubscriptionNode": { "type": "object", "description": "[**Unsubscribe from Object**](https://docs.suprsend.com/docs/unsubscribe-from-object): Removes users (actor or recipient) as subscribers from an object. Object must exist for the operation to succeed.", "required": [ "node_type", "name", "object_type", "object_id", "user_selection" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Unsubscribe from project" }, "node_type": { "type": "string", "const": "objectoperation_removesubscription" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "is_object_id_dynamic": { "type": "boolean", "default": false, "description": "Whether object_type and object_id are static literal strings or handlebars expressions." }, "object_type": { "type": "string", "description": "Type/collection name of the object.", "minLength": 1 }, "object_id": { "type": "string", "description": "Unique identifier of the object within the object_type.", "minLength": 1 }, "user_selection": { "type": "array", "description": "Which users to remove as subscribers from the object. Can select actor, recipient, or both.", "minItems": 1, "items": { "type": "string", "enum": [ "actor", "recipient" ] } } } }, "UserUpdateNode": { "type": "object", "description": "[**Update User Profile**](https://docs.suprsend.com/docs/update-user-profile): Updates user profile properties for either the actor or recipient using JSONNET expression.", "required": [ "node_type", "name", "user_selection", "properties" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Update user profile" }, "node_type": { "type": "string", "const": "userupdate" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "user_selection": { "type": "string", "enum": [ "actor", "recipient" ], "description": "Select which user to update - actor who triggered the workflow or the recipient of the workflow." }, "properties": { "type": "string", "description": "JSONNET script that evaluates at runtime to a map/dictionary of user properties to update.", "minLength": 1, "example": "{\"name\": \"John Doe\", \"email\": \"john.doe@example.com\"}" } } }, "InvokeWorkflowNode": { "type": "object", "description": "[**Invoke Workflow**](https://docs.suprsend.com/docs/invoke-workflow): Triggers another workflow using data from the current workflow run. Generally used when you have to notify different recipients at different stages of the workflow.", "required": [ "node_type", "name", "workflow", "recipient_selection" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Escalate to the manager" }, "node_type": { "type": "string", "const": "invokeworkflow" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "workflow": { "type": "string", "description": "Slug of the workflow to invoke.", "minLength": 1, "maxLength": 255, "pattern": "^[a-z0-9-_]+$" }, "actor_selection": { "type": "string", "enum": [ null, "recipient", "actor", "expression" ], "description": "Where to pick the actor from for the invoke-workflow payload. \n\n**recipient**: Use the recipient of the current workflow run. \n\n**actor**: Use the actor who triggered the current workflow run. \n\n**expression**: Use a JSONNET expression to derive the actor at runtime using data from the current workflow run." }, "actor_expression": { "type": "string", "description": "JSONNET expression to derive the actor at runtime for the invoked workflow. Pass when `actor_selection` is 'expression'. Eg. `data[\"$recipient\"].id`", "minLength": 1 }, "recipient_selection": { "type": "string", "enum": [ "recipient", "actor", "expression" ], "description": "Where to pick the recipient from for the invoke-workflow payload. \n\n**recipient**: Use the recipient of the current workflow run. \n\n**actor**: Use the actor who triggered the current workflow run. \n\n**expression**: Use a JSONNET expression to derive the recipient at runtime using data from the current workflow run." }, "recipient_expression": { "type": "string", "description": "JSONNET expression to derive the recipient at runtime for the invoked workflow. Pass when `recipient_selection` is 'expression'. Eg. `data[\"$recipient\"].manager_id`", "minLength": 1 }, "data": { "type": "string", "description": "JSONNET expression to derive the data field for the invoke-workflow payload." }, "append_current_run_data": { "type": "boolean", "description": "Whether the current workflow-run data should be passed as payload of the invoked workflow." } } }, "SendEmailNode": { "type": "object", "description": "[**Email**](https://docs.suprsend.com/docs/delivery-single-channel): Sends email notifications using a specified template.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send welcome email" }, "node_type": { "type": "string", "const": "send_email" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for notification content.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" } } }, "SendSmsNode": { "type": "object", "description": "[**SMS**](https://docs.suprsend.com/docs/delivery-single-channel)): Sends SMS text message notifications using a specified template.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send OTP SMS" }, "node_type": { "type": "string", "const": "send_sms" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for SMS notification content.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" } } }, "SendWhatsappNode": { "type": "object", "description": "[**WhatsApp**](https://docs.suprsend.com/docs/delivery-single-channel): Sends WhatsApp message notifications using a specified template.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send WhatsApp order confirmation" }, "node_type": { "type": "string", "const": "send_whatsapp" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for WhatsApp notification content.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" } } }, "SendMobilePushNode": { "type": "object", "description": "[**Mobile Push**](https://docs.suprsend.com/docs/delivery-single-channel): Sends push notifications to mobile devices (Android and iOS) using a specified template.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send mobile push notification" }, "node_type": { "type": "string", "const": "send_mobile_push" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for mobile push notification content.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" } } }, "SendInboxNode": { "type": "object", "description": "[**Inbox**](https://docs.suprsend.com/docs/delivery-single-channel): Sends in-app inbox notifications using a specified template.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send in-app notification" }, "node_type": { "type": "string", "const": "send_inbox" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for in-app inbox notification content.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" } } }, "SendWebpushNode": { "type": "object", "description": "[**Web Push**](https://docs.suprsend.com/docs/delivery-single-channel): Sends web push notifications using a specified template.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send web push notification" }, "node_type": { "type": "string", "const": "send_webpush" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for web push notification content.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" } } }, "SendSlackNode": { "type": "object", "description": "[**Slack**](https://docs.suprsend.com/docs/delivery-single-channel): Sends Slack message notifications using a specified template.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send Slack notification" }, "node_type": { "type": "string", "const": "send_slack" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for Slack notification content.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" } } }, "SendMsTeamsNode": { "type": "object", "description": "[**Microsoft Teams**](https://docs.suprsend.com/docs/delivery-single-channel): Sends Microsoft Teams chat notifications using a specified template.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send Teams notification" }, "node_type": { "type": "string", "const": "send_ms_teams" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for Microsoft Teams notification content.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" } } }, "SendMultiChannelNode": { "type": "object", "description": "[**Multi-Channel**](https://docs.suprsend.com/docs/delivery-multi-channel): Sends notifications across multiple channels simultaneously using a specified template.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send multi-channel notification" }, "node_type": { "type": "string", "const": "send_multi_channel" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for notification content across all channels.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" }, "channels": { "type": "array", "description": "Specific channels to use when sending multi-channel notification. If not provided, all channels will be used.", "required": true, "items": { "type": "string", "enum": [ "sms", "email", "androidpush", "iospush", "webpush", "inbox", "whatsapp", "slack", "ms_teams" ] } }, "channels_expr": { "type": "string", "description": "jq-expression for preparing channel list dynamically at runtime.", "minLength": 2 } } }, "SendSmartChannelRoutingNode": { "type": "object", "description": "[**Smart Channel Routing**](https://docs.suprsend.com/docs/smart-delivery): Sends notification subsequently at each consecutive channel with a delay (computed using time-to-live) between each channel.", "required": [ "node_type", "name", "template" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the node", "example": "Send smart channel notification" }, "node_type": { "type": "string", "const": "send_smart_channel_routing" }, "description": { "type": "string", "nullable": true, "description": "Description of what this node does" }, "template": { "type": "string", "description": "Slug of the template used for smart channel routing notification content.", "minLength": 1, "maxLength": 120, "pattern": "^[a-z0-9-_]+$" }, "channels": { "type": "array", "description": "Available channels for smart routing algorithm to choose from.", "items": { "type": "string", "enum": [ "sms", "email", "androidpush", "iospush", "webpush", "inbox", "whatsapp", "slack", "ms_teams" ] } }, "channels_expr": { "type": "string", "description": "jq-expression for preparing available channel list dynamically at runtime.", "minLength": 2 }, "success": { "type": "string", "description": "Success metric to track for smart channel routing.", "examples": { "delivered": { "summary": "Notification delivered", "value": "delivered" }, "seen": { "summary": "Notification seen", "value": "seen" }, "interacted": { "summary": "User clicked the notification", "value": "interacted" }, "custom_event": { "summary": "Custom event name", "value": "" } } }, "success_is_event": { "type": "boolean", "description": "Whether the success metric is a custom event. If not, notification status will be used to determine success." }, "ttl_value": { "type": "string", "description": "Time-to-live value for the smart channel routing notification in static duration format.", "example": "1h" }, "mandatory_channels": { "type": "array", "description": "Channels that will be sent immediately regardless of smart routing logic.", "items": { "type": "string", "enum": [ "sms", "email", "androidpush", "iospush", "webpush", "inbox", "whatsapp", "slack", "ms_teams" ] } }, "routing_basis": { "type": "string", "enum": [ "cost_low_to_high" ], "description": "Basis for smart channel routing. Determines the order in which channels are tried. Right now only `cost_low_to_high` is supported. We'll be adding more routing rules like in the order of engagement in future." } } }, "WorkflowCreateUpdate": { "type": "object", "required": [ "name", "trigger_type", "category", "tree" ], "properties": { "name": { "type": "string", "description": "Human-readable name of the workflow. Workflow slug is generated from this name for new workflows.", "example": "Welcome Sequence" }, "description": { "type": "string", "nullable": true, "description": "Description explaining the usecase of the workflow" }, "is_enabled": { "type": "boolean", "default": true, "description": "Whether the workflow should be enabled" }, "category": { "type": "string", "description": "Notification category of the workflow. Used to apply category-specific settings and preferences.", "example": "transactional" }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Tags are used for grouping and filtering workflows in list.", "example": "onboarding-sequence" }, "trigger_type": { "type": "string", "enum": [ "event", "api" ], "description": "You can trigger a workflow either via API by passing its slug directly, or through an event-based system where the workflow runs when a specific event occurs. You can compare both methods [here](https://docs.suprsend.com/docs/event-vs-api-trigger). If the workflow should run when a user enters or exits a list, use `trigger_type = event`." }, "payload_schema": { "type": "object", "nullable": true, "properties": { "schema": { "type": "string", "description": "Linked schema slug. You can create a schema via [Create Schema](/reference/create-schema) endpoint and then link it here.", "example": "onboarding-sequence-schema" }, "version_no": { "type": "integer", "description": "Schema version number to link. By default, live version is always picked for validation", "example": 1 } }, "description": "Schema to validate workflow api data structure. Used only when trigger_type = api." }, "trigger_events": { "type": "array", "items": { "type": "string" }, "description": "Events that trigger this workflow (required if trigger_type = event). In case of list entry/exit, event names will be `$USER_ENTERED_LIST - ` and `$USER_EXITED_LIST - ` respectively." }, "ratelimit": { "type": "object", "nullable": true, "description": "Throttle settings for the workflow. This is used to limit the number of times a workflow can be executed per user in a given time period.", "properties": { "count": { "type": "integer", "description": "Maximum number of executions allowed within the sliding window", "example": 4 }, "sliding_window": { "type": "string", "description": "Time window for rate limiting to be passed in format `00d00h00m00s`, d (days), h (hours), m (minutes), s (seconds). Rate limit is applied within this window.", "example": "6m" } } }, "conditions": { "type": "array", "nullable": true, "description": "Trigger Conditions. Workflow will be executed if any of the conditions in this array evaluate to true.", "items": { "type": "object", "properties": { "type": { "type": "string", "description": "Type of condition expression. Currently only `expression_v1` is supported.", "example": "expression_v1", "enum": [ "expression_v1" ] }, "expression_v1": { "type": "object", "description": "Expression object containing the condition logic", "properties": { "op": { "type": "string", "description": "Logical operator to combine conditions. Currently only `AND` is supported.", "enum": [ "AND" ] }, "args": { "type": "array", "description": "Array of conditions. Each condition is defined as key (variable) value. Refer to [how to construct a condition here](https://docs.suprsend.com/docs/branch#constructing-a-condition).", "items": { "type": "object", "properties": { "op": { "type": "string", "description": "Comparison operator between variable and value. Refer to list of [comparison operators here](https://docs.suprsend.com/docs/branch#key-value-pair).", "example": "==", "enum": [ "==", "!=", ">", "<", ">=", "<=", "EMPTY", "NON_EMPTY", "CONTAINS", "NOT_CONTAINS", "ARRAY_INTERSECTS", "NOT_ARRAY_INTERSECTS", "DATETIME_EQUALS", "DATETIME_LT", "DATETIME_GT" ] }, "value": { "type": "string", "description": "Value to compare against. Can add fixed value as \"..\" or variable in JSONNET format as data..", "example": "\"admin\"" }, "variable": { "type": "string", "description": "key from your trigger payload to compare the value against. Direct key name is passed here.", "example": "role" }, "variable_ns": { "type": "string", "description": "Variable namespace (empty for data passed in trigger, `$recipient` for recipient or object subscription properties, `$tenant` for tenant properties)", "example": "$recipient", "enum": [ "", "$recipient", "$tenant" ] } } } } } } } } }, "override_recipients_type": { "type": "string", "description": "Override recipients using a property from the trigger payload. Type defines if the workflow should run for a list of users or a single [object](https://docs.suprsend.com/docs/objects). Only applicable for trigger_type = `event`.", "example": "user", "enum": [ "user", "single_object_fields" ] }, "override_recipients_user_expr": { "type": "string", "nullable": true, "description": "JQ expression to override recipients when override_recipients_type = `user`. Only applicable for trigger_type = `event`.", "example": ".distinct_id" }, "override_recipients_single_object_fields_expr": { "type": "object", "nullable": true, "description": "JQ expression to override recipients with object when override_recipients_type = `single_object_fields`. Only applicable for trigger_type = `event`.", "properties": { "id": { "type": "string", "description": "JQ expression to extract object ID from trigger payload", "example": ".object_id" }, "object_type": { "type": "string", "description": "JQ expression to extract object type from trigger payload. You can also pass fixed value as \"..\".", "example": ".object_type" }, "$object_subscriptions_query.depth": { "type": "string", "description": "Depth [Optional] is used to specify how deep to traverse object subscriptions. `depth=0` would only send notification to object channels and not its subscribers, `depth=1` would fetch 1 level of subscriptions, `depth=2` (maximum) \u2192 Also fetches subscriptions of child objects, eg. teams -> team members>.", "example": "2" } }, "example": { "id": ".object_id", "object_type": ".object_type", "$object_subscriptions_query.depth": "2" } }, "override_actor_user_expr": { "type": "string", "nullable": true, "description": "JQ expression to override actor. Only applicable for trigger_type = `event`.", "example": ".actor_id" }, "override_tenant_expr": { "type": "string", "nullable": true, "description": "JQ expression to override [tenant](https://docs.suprsend.com/docs/tenants). Only applicable for trigger_type = `event`.", "example": ".tenant_id" }, "tree": { "type": "object", "properties": { "nodes": { "type": "array", "items": { "oneOf": [ { "$ref": "#/components/schemas/DelayNode" }, { "$ref": "#/components/schemas/BatchNode" }, { "$ref": "#/components/schemas/DigestNode" }, { "$ref": "#/components/schemas/HttpApiWebhookNode" }, { "$ref": "#/components/schemas/HttpApiFetchNode" }, { "$ref": "#/components/schemas/BranchWaitUntilNode" }, { "$ref": "#/components/schemas/BranchNode" }, { "$ref": "#/components/schemas/TransformNode" }, { "$ref": "#/components/schemas/TimeWindowNode" }, { "$ref": "#/components/schemas/SubscriberListOperationAddUserNode" }, { "$ref": "#/components/schemas/SubscriberListOperationRemoveUserNode" }, { "$ref": "#/components/schemas/ObjectOperationAddSubscriptionNode" }, { "$ref": "#/components/schemas/ObjectOperationRemoveSubscriptionNode" }, { "$ref": "#/components/schemas/UserUpdateNode" }, { "$ref": "#/components/schemas/InvokeWorkflowNode" }, { "$ref": "#/components/schemas/SendEmailNode" }, { "$ref": "#/components/schemas/SendSmsNode" }, { "$ref": "#/components/schemas/SendWhatsappNode" }, { "$ref": "#/components/schemas/SendMobilePushNode" }, { "$ref": "#/components/schemas/SendInboxNode" }, { "$ref": "#/components/schemas/SendWebpushNode" }, { "$ref": "#/components/schemas/SendSlackNode" }, { "$ref": "#/components/schemas/SendMsTeamsNode" }, { "$ref": "#/components/schemas/SendMultiChannelNode" }, { "$ref": "#/components/schemas/SendSmartChannelRoutingNode" } ] }, "description": "Array of nodes in the workflow tree structure." } }, "description": "Node tree structure of the workflow. Contains the nodes array with all workflow nodes and their configuration." } } }, "ErrorResponse": { "type": "object", "properties": { "code": { "type": "integer", "description": "HTTP status code" }, "error_code": { "type": "string", "description": "Specific error code identifier" }, "type": { "type": "string", "description": "Error type classification" }, "message": { "type": "string", "description": "Human-readable error message" }, "detail": { "type": "string", "description": "Additional error details" } } }, "MessageResponse": { "type": "object", "description": "A single notification delivery attempt produced by a workflow trigger or broadcast.", "properties": { "message_id": { "type": "string", "description": "Message-id to update." }, "created_at": { "type": "string", "format": "date-time", "description": "Time when the message entry was created." }, "updated_at": { "type": "string", "format": "date-time", "description": "Time when the message entry was last updated (for example, on a status or timestamp change)." }, "triggered_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Time when the message was handovered to vendor by SuprSend." }, "delivered_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Time when the vendor confirmed successful delivery. Null if the message has not been delivered yet. If you're not getting delivery events for email, SMS and Whatsapp, make sure to configure SuprSend webhook URL in vendor portal." }, "seen_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Time when the recipient first saw or opened the message. Seen tracking is available for all channels accept Slack, MS Teams and SMS." }, "clicked_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Time when the recipient clicked or interacted with the message. Tracked for Email, Push and Inbox." }, "dismissed_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Time when the recipient dismissed or cleared the message. Only application for mobile push notifications." }, "read_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Time when the message was marked as read. Only applicable for Inbox channel." }, "unread_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Time when a previously read message was marked unread. Only applicable for Inbox channel." }, "archived_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Time when the message was archived. Only applicable for Inbox channel." }, "unarchived_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Time when a previously archived message was unarchived. Only applicable for Inbox channel." }, "is_read": { "type": "boolean", "description": "Whether the message is currently in the read state. Only applicable for Inbox channel." }, "is_archived": { "type": "boolean", "description": "Whether the message is currently archived. Only applicable for Inbox channel." }, "status": { "type": "string", "description": "Current message status. Other than `archived`, all actions translate to a status. Archived is just a flag on the message.\n\n- `triggered` - Message has been triggered by SuprSend and queued for delivery to the vendor.\n- `trigger_failed` - Vendor reported failure in response to delivery API call itself.\n- `trigger_blocked` - Test mode is enabled and this channel was not part of allowed channel list.\n- `not_to_be_triggered` - Message was intentionally skipped (generally happens in smart delivery when success metric is achieved)\n- `to_be_triggered` - Message is queued and waiting to be triggered (generally happens when there is a wait added in smart delivery)\n- `sent_by_vendor` - Vendor accepted the message for delivery; final delivery confirmation is pending.\n- `delivered` - Vendor confirmed successful delivery to the recipient.\n- `delivery_failure` - Vendor reported a delivery failure (for example, bounce or invalid recipient).\n- `seen` - Recipient saw or opened the message.\n- `clicked` - Recipient clicked or interacted with the message.\n- `dismissed` - Recipient dismissed the message without acting on it.\n- `read` - Inbox message was marked as read by the recipient.\n", "enum": [ "triggered", "trigger_failed", "trigger_blocked", "not_to_be_triggered", "to_be_triggered", "sent_by_vendor", "delivered", "delivery_failure", "seen", "clicked", "dismissed", "read" ] }, "channel": { "type": "string", "description": "Channel through which the message was sent.", "enum": [ "sms", "email", "whatsapp", "inbox", "androidpush", "iospush", "webpush", "slack", "ms_teams" ] }, "idempotency_key": { "type": "string", "description": "Idempotency key supplied at trigger time to prevent duplicate sends for the same logical event." }, "failure_reason": { "type": "string", "description": "Human-readable reason describing why delivery failed. Empty when the message did not fail." }, "recipient": { "type": "object", "description": "Recipient of the message. Either a user (`$type: user`) or an object (`$type: object`).", "properties": { "$type": { "type": "string", "description": "Recipient type - `user` for a user recipient or `object` for an object recipient.", "enum": [ "user", "object" ] }, "distinct_id": { "type": "string", "description": "Distinct ID of the user recipient. Present when `$type` is `user`." }, "object_type": { "type": "string", "description": "Object type slug. Present when `$type` is `object`." }, "id": { "type": "string", "description": "Object ID. Present when `$type` is `object`." } } }, "parent_entity_id": { "type": "string", "description": "ID of the parent entity (object)" }, "parent_entity_type": { "type": "string", "description": "Type of the parent entity that originated this message (object)" }, "vendor": { "type": "object", "description": "Delivery vendor that handled this message.", "properties": { "name": { "type": "string", "description": "Internal name of the vendor integration (for example, `sendgrid`, `twilio`)." }, "nickname": { "type": "string", "description": "User-defined nickname for the vendor integration in the SuprSend dashboard." } } }, "execution_id": { "type": "string", "description": "ID of the workflow execution this message belongs to." }, "parent_execution_id": { "type": "string", "description": "ID of the parent execution, when this message was produced as fanout on object trigger." }, "is_campaign": { "type": "boolean", "description": "true when message was sent as part of a broadcast." }, "tenant_id": { "type": "string", "description": "ID of the tenant the message was sent under." }, "workflow": { "type": "object", "description": "Workflow that produced the message.", "properties": { "slug": { "type": "string", "description": "Unique slug of the workflow." }, "version_id": { "type": "string", "description": "ID of the specific workflow version that ran." }, "name": { "type": "string", "description": "Human-readable name of the workflow." }, "node_ref": { "type": "string", "description": "Slug to the specific node within the workflow that emitted this message." } } }, "template": { "type": "object", "description": "Template used to render the message.", "properties": { "name": { "type": "string", "description": "Human-readable name of the template." }, "slug": { "type": "string", "description": "Unique slug of the template." }, "version_no": { "type": "integer", "description": "Version number of the template that was used to render the message." } } }, "channel_identity": { "type": "object", "additionalProperties": true, "description": "Channel-specific recipient identity that the message was delivered to (for example, the phone number for SMS, email address for email). Credential keys (`access_token`, `keys`, `incoming_webhook`) are stripped from the response.", "example": { "sms": "+15555550100" } }, "category": { "type": "string", "description": "Notification category slug associated with this message." } } }, "CursorPagination": { "type": "object", "properties": { "count": { "type": "integer", "description": "Total matching records (ignores cursor position)." }, "limit": { "type": "integer", "description": "Maximum number of results returned per page." }, "has_prev": { "type": "boolean", "description": "True when the previous page (newer logs) exists." }, "before": { "type": "string", "nullable": true, "description": "Cursor to pass as `before=` to retrieve the previous page (newer logs). Null on the first page or when `has_prev` is false." }, "has_next": { "type": "boolean", "description": "True when an next page (older logs) exist." }, "after": { "type": "string", "nullable": true, "description": "Cursor to pass as `after=` to retrieve the next page (older logs). Null when `has_next` is false." } } }, "BulkPatchItemResult": { "type": "object", "description": "Per-message outcome from the bulk patch endpoint. Success is implied by a null `error` field.", "properties": { "message_id": { "type": "string", "description": "Message-id to update." }, "status_code": { "type": "integer", "description": "Per-item status code:\n- `202` - success\n- `404` - `not_found`\n- `422` - `status_blocked` or `action_not_supported`\n- `500` - `internal_error`\n" }, "error": { "type": "object", "nullable": true, "description": "Null on success, populated on failure.", "required": [ "type", "message" ], "properties": { "type": { "type": "string", "description": "Machine-readable key for why the item failed:\n- `not_found` - message_id not found in this workspace\n- `status_blocked` - message is in a terminal state (`trigger_failed`, `trigger_blocked`, `failure_by_vendor`, `not_to_be_triggered`) that cannot be overridden\n- `action_not_supported` - action is invalid for the message's channel (for example, `dismissed` on inbox, `read` on sms)\n- `internal_error` - Internal error at SuprSend end. Reach out to support if you get this error code.\n", "enum": [ "not_found", "status_blocked", "action_not_supported", "internal_error" ] }, "message": { "type": "string", "description": "Human-readable detail. Do not parse programmatically." } } } } }, "WorkspaceCreate": { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "description": "Workspace name" }, "description": { "type": "string", "description": "Optional human-readable description" } } }, "WorkspaceApiKeyCreate": { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "description": "Label for the API key" }, "description": { "type": "string", "description": "Optional notes for operators" } } }, "DisableWorkspaceApiKeyRequest": { "type": "object", "required": [ "is_disabled" ], "properties": { "is_disabled": { "type": "boolean", "description": "Set to true to disable the API key" } } }, "WorkspacePublicKeyCreate": { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "description": "Label for the public key" }, "description": { "type": "string", "description": "Optional notes" } } }, "PatchWorkspacePublicKeyRequest": { "type": "object", "required": [ "is_secure_mode_enabled" ], "properties": { "is_secure_mode_enabled": { "type": "boolean", "description": "Enable or disable secure mode for this public key" } } }, "RollWorkspaceSigningKeyRequest": { "type": "object", "properties": { "expiry_at": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp when the previous signing key material should expire" } } }, "ManagementListMeta": { "type": "object", "description": "Pagination metadata (when applicable)", "properties": { "count": { "type": "integer", "description": "Total items matching the query" }, "limit": { "type": "integer", "nullable": true, "description": "Maximum number of results returned per page." }, "offset": { "type": "integer", "nullable": true, "description": "Starting position of the returned results." } } }, "ManagementActor": { "type": "object", "description": "Identity that performed an action (created, updated, rolled, deleted, rotated).", "nullable": true, "properties": { "name": { "type": "string", "description": "Display name of the actor.", "example": "System User" }, "email": { "type": "string", "description": "Email address of the actor.", "example": "user@example.com" } } }, "ManagementWorkspace": { "type": "object", "description": "Workspace record returned by the Management API.", "properties": { "uid": { "type": "string", "description": "Unique workspace identifier.", "example": "wksp_exampleUid01" }, "slug": { "type": "string", "description": "Workspace slug used in API paths (e.g. `staging`, `production`).", "example": "staging" }, "data_center": { "type": "object", "description": "Data center metadata associated with the workspace.", "additionalProperties": true }, "is_expired": { "type": "boolean", "description": "Indicates whether the workspace has expired." }, "has_limit_reached": { "type": "boolean", "description": "Indicates whether the workspace has reached its plan limit." }, "name": { "type": "string", "description": "Human-readable workspace name.", "example": "Staging" }, "description": { "type": "string", "nullable": true, "description": "Optional workspace description." }, "mode": { "type": "string", "description": "Workspace mode. **sandbox** is pre-created by SuprSend for early testing with pre-configured vendors, **staging** will be your testing workspace and **production** will be the one you'll use to send to your actual users.", "enum": [ "sandbox", "production" ] } } }, "ManagementWorkspaceListResponse": { "type": "object", "properties": { "meta": { "$ref": "#/components/schemas/ManagementListMeta" }, "results": { "type": "array", "items": { "$ref": "#/components/schemas/ManagementWorkspace" } } } }, "WorkspaceCreateRequest": { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "description": "Workspace name.", "example": "my-workspace" }, "description": { "type": "string", "nullable": true, "description": "Optional workspace description.", "example": "Testing workspace API" } } }, "ManagementWorkspaceApiKey": { "type": "object", "description": "Workspace-scoped REST API key (server-side secret).", "properties": { "id": { "type": "string", "description": "Unique identifier of the API key.", "example": "ws_apik_exampleId01" }, "masked_api_key": { "type": "string", "description": "Masked preview of the API key used in list responses.", "example": "SS.XXXXXXX*****" }, "is_deleted": { "type": "boolean", "description": "Indicates whether the API key has been deleted." }, "name": { "type": "string", "description": "Label for the API key.", "example": "backend-prod" }, "allowed_domains": { "type": "array", "items": { "type": "string" }, "description": "Domains allowed to use this key." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the API key was created." }, "created_by": { "$ref": "#/components/schemas/ManagementActor" }, "deleted_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Timestamp when the API key was deleted, if applicable." }, "deleted_by": { "$ref": "#/components/schemas/ManagementActor" } } }, "ManagementWorkspaceApiKeyCreateResponse": { "allOf": [ { "$ref": "#/components/schemas/ManagementWorkspaceApiKey" }, { "type": "object", "properties": { "api_key": { "type": "string", "description": "Full secret API key. Returned only once at creation - store it securely and never commit to source control.", "example": "SS.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" } } } ] }, "ManagementWorkspaceApiKeyListResponse": { "type": "object", "properties": { "meta": { "$ref": "#/components/schemas/ManagementListMeta" }, "results": { "type": "array", "items": { "$ref": "#/components/schemas/ManagementWorkspaceApiKey" } } } }, "WorkspaceApiKeyCreateRequest": { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "description": "Label for the API key.", "example": "backend-prod" }, "description": { "type": "string", "nullable": true, "description": "Optional notes for operators." } } }, "ManagementWorkspacePublicKey": { "type": "object", "description": "Workspace public key used by client SDKs.", "properties": { "id": { "type": "string", "description": "Unique identifier of the public key.", "example": "ws_pubk_exampleId01" }, "api_key": { "type": "string", "description": "Public key value exposed to clients.", "example": "SS.PUBK.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, "name": { "type": "string", "description": "Label for the public key.", "example": "web-app" }, "allowed_domains": { "type": "array", "nullable": true, "items": { "type": "string" }, "description": "Domains allowed to use this public key." }, "is_secure_mode_enabled": { "type": "boolean", "description": "Indicates whether secure mode is enabled for this key." }, "is_deleted": { "type": "boolean", "description": "Indicates whether the public key has been deleted." }, "is_default": { "type": "boolean", "description": "Indicates whether this is the default public key for the workspace." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the public key was created." }, "created_by": { "$ref": "#/components/schemas/ManagementActor" }, "rotated_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Timestamp when the public key was last rotated." }, "rotated_by": { "$ref": "#/components/schemas/ManagementActor" }, "updated_at": { "type": "string", "format": "date-time", "description": "Timestamp when the public key was last updated." }, "updated_by": { "$ref": "#/components/schemas/ManagementActor" } } }, "ManagementWorkspacePublicKeyListResponse": { "type": "object", "properties": { "meta": { "$ref": "#/components/schemas/ManagementListMeta" }, "results": { "type": "array", "items": { "$ref": "#/components/schemas/ManagementWorkspacePublicKey" } } } }, "WorkspacePublicKeyCreateRequest": { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "description": "Label for the public key.", "example": "web-app" }, "description": { "type": "string", "nullable": true, "description": "Optional notes." } } }, "WorkspacePublicKeyPatchRequest": { "type": "object", "required": [ "is_secure_mode_enabled" ], "properties": { "is_secure_mode_enabled": { "type": "boolean", "description": "Enable or disable secure mode for this public key." } } }, "ManagementWorkspaceSigningKey": { "type": "object", "description": "Signing key used to verify signed payloads.", "properties": { "id": { "type": "string", "description": "Unique identifier of the signing key.", "example": "ws_signk_exampleId01" }, "uid": { "type": "string", "description": "Signing key uid used in path parameters for roll/delete.", "example": "signing_key_exampleUid01" }, "status": { "type": "string", "description": "Status of the signing key.", "enum": [ "active", "rolled" ] }, "allowed_domains": { "type": "array", "nullable": true, "items": { "type": "string" }, "description": "Domains allowed to use this signing key." }, "expiry_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Timestamp when the signing key expires." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the signing key was created." }, "created_by": { "$ref": "#/components/schemas/ManagementActor" }, "rolled_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Timestamp when the signing key was rolled." }, "rolled_by": { "$ref": "#/components/schemas/ManagementActor" }, "deleted_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Timestamp when the signing key was deleted." }, "deleted_by": { "$ref": "#/components/schemas/ManagementActor" } } }, "ManagementWorkspaceSigningKeyCreateResponse": { "allOf": [ { "$ref": "#/components/schemas/ManagementWorkspaceSigningKey" }, { "type": "object", "properties": { "private_key_pem": { "type": "string", "description": "PEM-encoded private key. Returned only at creation and on roll - store it securely and never commit to source control.", "example": "-----BEGIN PRIVATE KEY-----\n...redacted...\n-----END PRIVATE KEY-----\n" }, "private_key_base64": { "type": "string", "description": "Base64-encoded private key. Returned only at creation and on roll.", "example": "LS0tLS1CRUdJTi...redacted..." } } } ] }, "ManagementWorkspaceSigningKeyListResponse": { "type": "object", "properties": { "meta": { "$ref": "#/components/schemas/ManagementListMeta" }, "results": { "type": "array", "items": { "$ref": "#/components/schemas/ManagementWorkspaceSigningKey" } } } } } }