Surfaces
Agent-generated data collection interfaces: SurfaceSpec, fields, channels, lifecycle, and submission handling.
Surfaces are agent-generated data collection interfaces delivered to patients through supported communication channels. Agents analyze entity state and data gaps in the world model, generate a SurfaceSpec, and the platform renders and delivers it. Submissions return as source-attributed world-model events; any later external delivery follows a separate connector policy.
Voice Agent Surface Tools
A family of context graph tools allows voice agents to create and manage surfaces during live calls:
create_surface
entity_id (required), title (required), fields (required, list), description, channel, expires_in_hours, resource_type, context
surface_id, url, status, expires_at
create_surface_from_template
template_id (required), entity_id (required)
surface_id, url, status, prefilled_count, total_fields. Resolves a form template against the patient's entity state, prefilling fields with known data.
get_form_templates
optional category, patient_type filters
Reusable form templates for the workspace
deliver_surface
surface_id (required), channel_address (required: phone number or email)
surface_id, url, status
check_surface_status
surface_id (required)
surface_id, status, title, fields_count, entity_id, created_at
get_surface_progress
surface_id (required)
Field-level completion status (which fields are filled vs empty)
reshape_surface
surface_id (required)
New surface_id and url containing only the unfilled fields from an abandoned form
list_entity_surfaces
entity_id (required), status (optional filter)
surfaces[] (id, title, status, channel, created_at), count
get_surface_insights
entity_id (required)
entity_id, completion_rate, preferred_channel, total_surfaces, completed, pending_surfaces, recent_surfaces[]
extract_surface_file_text
surface_id (required)
Readable text extracted from submitted PDF file fields
get_surface_insights queries the entity's surface analytics before creating new surfaces. Returns completion rate, preferred channel, and count of pending (unfinished) surfaces. Call this before create_surface to avoid surface fatigue: if a patient already has multiple pending surfaces or a low completion rate, the agent may choose to collect data verbally instead.
These tools proxy through the Platform API surface endpoints. Authentication uses the call's agent_session JWT, which is workspace-scoped, so surface operations are automatically isolated to the correct workspace.
All of these tools handle errors gracefully: if the Platform API is unreachable, the agent receives an error message rather than an exception, so it can continue the call.
Permissions
Two scopes control surface access:
surfaces:read
View surface specs, submissions, and lifecycle status
surfaces:write
Generate new surface specs
Both scopes are included in the member role by default. RBAC enforcement is applied on all surface CRUD routes (view, create, update, delete).
Management API
Create a Surface
Create a new data collection surface.
Stores the surface spec as a world.event with domain="surface". The entity_id is stored inside event data (not on the event row) to avoid entity state recomputation.
Returns a signed patient-facing token and URL if SURFACE_TOKEN_SECRET is configured.
Permissions: member, admin, owner (surfaces:write)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Request to create a new surface.
The agent generates a SurfaceSpec and sends it here.
Delivery channels for surfaces.
webPossible values: 168Successful Response
Lifecycle status of a surface.
Delivery channels for surfaces.
Validation error
Rate limited
POST /v1/{workspace_id}/surfaces HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 892
{
"entity_id": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"fields": [
{
"key": "text",
"label": "text",
"field_type": "text",
"required": true,
"options": [
"text"
],
"description": "text",
"placeholder": "text",
"prefill_value": null,
"validation": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"sensitive": false,
"condition": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"consent_text": "text"
}
],
"channel": "web",
"use_case_id": "123e4567-e89b-12d3-a456-426614174000",
"expires_in_hours": 168,
"context": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"resource_type": "text",
"branding": {
"logo_url": "text",
"primary_color": "text",
"background_color": "text",
"font_family": "text"
},
"sections": [
{
"title": "text",
"description": "text",
"field_keys": [
"text"
],
"condition": {
"ANY_ADDITIONAL_PROPERTY": "anything"
}
}
],
"completion_title": "text",
"completion_message": "text",
"completion_action_url": "text",
"submit_button_text": "text"
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"event_id": "123e4567-e89b-12d3-a456-426614174000",
"entity_id": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"status": "created",
"channel": "email",
"use_case_id": "123e4567-e89b-12d3-a456-426614174000",
"fields_count": 1,
"expires_at": "text",
"created_at": "text",
"token": "text",
"url": "text"
}List Surfaces
List surfaces with pagination and optional filters.
Permissions: viewer, member, admin, owner (surfaces:read)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
50Filter by entity ID
Filter by status
Filter by channel
Successful Response
Validation Error
Rate limited
GET /v1/{workspace_id}/surfaces HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"items": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"event_id": "123e4567-e89b-12d3-a456-426614174000",
"entity_id": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"status": "created",
"channel": "email",
"use_case_id": "123e4567-e89b-12d3-a456-426614174000",
"fields_count": 1,
"fields": [
{
"ANY_ADDITIONAL_PROPERTY": "anything"
}
],
"resource_type": "text",
"context": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"expires_at": "text",
"created_at": "text",
"delivered_at": "text",
"opened_at": "text",
"submitted_at": "text",
"submitted_data": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"delivery_metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"review_notes": "text",
"reviewed_by": "123e4567-e89b-12d3-a456-426614174000",
"reviewed_at": "text",
"archived_at": "text",
"archive_reason": "text",
"url": "text"
}
],
"has_more": true,
"continuation_token": null
}Get a Surface
Get a surface by ID.
Returns the surface spec and current lifecycle status. Also mints the
patient-facing url so operators can copy/share the link from the read
view (the token isn't stored, so it's re-minted on each read).
Permissions: viewer, member, admin, owner (surfaces:read)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Lifecycle status of a surface.
Delivery channels for surfaces.
Surface not found
Validation Error
Rate limited
GET /v1/{workspace_id}/surfaces/{surface_id} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"event_id": "123e4567-e89b-12d3-a456-426614174000",
"entity_id": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"status": "created",
"channel": "email",
"use_case_id": "123e4567-e89b-12d3-a456-426614174000",
"fields_count": 1,
"fields": [
{
"ANY_ADDITIONAL_PROPERTY": "anything"
}
],
"resource_type": "text",
"context": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"expires_at": "text",
"created_at": "text",
"delivered_at": "text",
"opened_at": "text",
"submitted_at": "text",
"submitted_data": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"delivery_metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"review_notes": "text",
"reviewed_by": "123e4567-e89b-12d3-a456-426614174000",
"reviewed_at": "text",
"archived_at": "text",
"archive_reason": "text",
"url": "text"
}Update a Surface
Update an existing surface spec.
Only allowed while status is CREATED or DELIVERED. Writes a surface.updated event preserving the full audit trail.
Permissions: member, admin, owner (Surface:Create)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Partial update to an existing surface.
All fields are optional. Only provided fields are merged into the spec. Only allowed while status is CREATED or DELIVERED.
Delivery channels for surfaces.
Successful Response
Lifecycle status of a surface.
Delivery channels for surfaces.
Surface not found
Cannot update in current status
Validation error
Rate limited
PATCH /v1/{workspace_id}/surfaces/{surface_id} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 718
{
"title": "text",
"description": "text",
"fields": [
{
"key": "text",
"label": "text",
"field_type": "text",
"required": true,
"options": [
"text"
],
"description": "text",
"placeholder": "text",
"prefill_value": null,
"validation": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"sensitive": false,
"condition": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"consent_text": "text"
}
],
"branding": {
"logo_url": "text",
"primary_color": "text",
"background_color": "text",
"font_family": "text"
},
"sections": [
{
"title": "text",
"description": "text",
"field_keys": [
"text"
],
"condition": {
"ANY_ADDITIONAL_PROPERTY": "anything"
}
}
],
"completion_title": "text",
"completion_message": "text",
"completion_action_url": "text",
"submit_button_text": "text",
"channel": "email",
"resource_type": "text"
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"event_id": "123e4567-e89b-12d3-a456-426614174000",
"entity_id": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"status": "created",
"channel": "email",
"use_case_id": "123e4567-e89b-12d3-a456-426614174000",
"fields_count": 1,
"fields": [
{
"ANY_ADDITIONAL_PROPERTY": "anything"
}
],
"resource_type": "text",
"context": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"expires_at": "text",
"created_at": "text",
"delivered_at": "text",
"opened_at": "text",
"submitted_at": "text",
"submitted_data": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"delivery_metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"review_notes": "text",
"reviewed_by": "123e4567-e89b-12d3-a456-426614174000",
"reviewed_at": "text",
"archived_at": "text",
"archive_reason": "text",
"url": "text"
}Archive a Surface
Archive (soft-delete) a surface.
Works for any non-terminal surface. Terminal surfaces (completed, expired, already archived) cannot be archived.
Permissions: member, admin, owner (Surface:Create)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Surface not found
Cannot archive terminal surface
Validation Error
Rate limited
DELETE /v1/{workspace_id}/surfaces/{surface_id} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"surface_id": "123e4567-e89b-12d3-a456-426614174000",
"status": "text"
}List Surfaces Pending Review
List surfaces pending review.
Field engineers use this to approve or reject surfaces before delivery.
Permissions: operator, member, admin, owner (ReviewQueue:View)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
50Successful Response
Validation Error
Rate limited
GET /v1/{workspace_id}/surfaces/review HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"items": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"event_id": "123e4567-e89b-12d3-a456-426614174000",
"entity_id": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"status": "created",
"channel": "email",
"use_case_id": "123e4567-e89b-12d3-a456-426614174000",
"fields_count": 1,
"fields": [
{
"ANY_ADDITIONAL_PROPERTY": "anything"
}
],
"resource_type": "text",
"context": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"expires_at": "text",
"created_at": "text",
"delivered_at": "text",
"opened_at": "text",
"submitted_at": "text",
"submitted_data": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"delivery_metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"review_notes": "text",
"reviewed_by": "123e4567-e89b-12d3-a456-426614174000",
"reviewed_at": "text",
"archived_at": "text",
"archive_reason": "text",
"url": "text"
}
],
"has_more": true,
"continuation_token": null
}Approve a Surface
Approve a surface pending review.
The surface returns to CREATED status and can then be delivered.
Permissions: operator, member, admin, owner (ReviewQueue:Review)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Lifecycle status of a surface.
Surface not found
Surface is not pending review
Validation Error
Rate limited
POST /v1/{workspace_id}/surfaces/{surface_id}/approve HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"surface_id": "123e4567-e89b-12d3-a456-426614174000",
"status": "created",
"action": "approved"
}Reject a Surface
Reject a surface pending review.
The surface is marked as expired and will not be delivered.
Permissions: operator, member, admin, owner (ReviewQueue:Review)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Lifecycle status of a surface.
Surface not found
Surface is not pending review
Validation Error
Rate limited
POST /v1/{workspace_id}/surfaces/{surface_id}/reject HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 17
{
"reason": "text"
}{
"surface_id": "123e4567-e89b-12d3-a456-426614174000",
"status": "created",
"action": "approved"
}Reshape a Surface
Create a new surface with only the unfilled fields from the original.
Used for re-engaging patients who abandoned a form. The new surface contains only the fields they haven't completed yet, reducing friction.
Permissions: member, admin, owner (surfaces:write)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Lifecycle status of a surface.
Delivery channels for surfaces.
Surface not found
All fields already filled
Validation Error
Rate limited
POST /v1/{workspace_id}/surfaces/{surface_id}/reshape HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"event_id": "123e4567-e89b-12d3-a456-426614174000",
"entity_id": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"status": "created",
"channel": "email",
"use_case_id": "123e4567-e89b-12d3-a456-426614174000",
"fields_count": 1,
"expires_at": "text",
"created_at": "text",
"token": "text",
"url": "text"
}Get Surface Progress
Get field-level completion status for a surface.
Returns which fields are filled vs empty, useful for abandonment intelligence and targeted re-engagement.
Permissions: viewer, member, admin, owner (surfaces:read)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Surface not found
Validation Error
Rate limited
GET /v1/{workspace_id}/surfaces/{surface_id}/progress HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"surface_id": "123e4567-e89b-12d3-a456-426614174000",
"total_fields": 1,
"filled_count": 1,
"empty_count": 1,
"filled_keys": [
"text"
],
"empty_keys": [
"text"
],
"required_empty_keys": [
"text"
]
}Deliver a Surface
Record a real delivery handoff for a surface.
Email targets are delivered through channel-manager's
POST /v1/email/ (CM owns SES sender identity, IP pool, DKIM,
suppression — keyed on the surface row's use_case_id). Phone-shaped
addresses return 422 — SMS surface delivery was removed in PR #2783.
Other targets record an external handoff that was completed outside
platform-api.
Permissions: member, admin, owner (surfaces:write)
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Request to mark a surface as delivered.
Delivery address (phone number, email, etc.)
Successful Response
Delivery channels for surfaces.
Surface not found
Surface already delivered/completed/expired
Validation error
Rate limited
POST /v1/{workspace_id}/surfaces/{surface_id}/deliver HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 26
{
"channel_address": "text"
}{
"surface_id": "123e4567-e89b-12d3-a456-426614174000",
"status": "delivered",
"channel": "email",
"url": "text",
"channel_address": "text",
"message_id": "text",
"from_number": "text",
"from_address": "text",
"delivery_provider": "text",
"delivered_at": "text"
}The delivery endpoint sends the surface URL to the patient, marks the surface as delivered, writes an audit event, and publishes a surface.delivered SSE event for real-time dashboards.
Delivery behavior: email-shaped delivery targets are sent through the workspace's configured email transport (the surface must have been created with channel='email' and a bound use_case_id). The email body contains a short redirect link (/s/f/{surface_id}) that 302-redirects to the full signed token URL. Non-email, non-phone targets record a web handoff. Phone-number targets are rejected with 422.
Error responses: the deliver endpoint returns 404 (surface not found), 409 (already delivered/completed/expired, or test surface), 422 (validation, including a rejected phone target), and 429 (rate limited). Email delivery additionally returns 503 when email transport is not configured.
Lifecycle SSE events: surface.delivered, surface.opened, surface.submitted are published in real time as they happen.
Surface expiry: Non-terminal surfaces (not yet completed) automatically expire after their configured TTL. Expired surfaces reject renders, submissions, and auto-saves.
Channels
email
Email with branded link
Web
web
Direct link for portals or dashboards
SMS
sms
Spec value only - link delivery is not supported (returns 422); use email or web
BrandingConfig
Visual branding applied to the patient-facing form. Can be set at workspace level (default for all surfaces) or per-surface (overrides workspace defaults).
Get Workspace Branding
Get the workspace default branding for surfaces.
Returns empty branding when not configured.
Permissions: authenticated (any role).
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Rate limited
GET /v1/{workspace_id}/settings/branding HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"branding": {
"logo_url": "text",
"primary_color": "text",
"background_color": "text",
"font_family": "text"
}
}Update Workspace Branding
Update the workspace default branding for surfaces.
Surface-level branding takes precedence over workspace-level branding.
Permissions: admin, owner.
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Update workspace branding. All fields are optional — only provided fields are changed.
Successful Response
Workspace not found
Validation error
Rate limited
PUT /v1/{workspace_id}/settings/branding HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 102
{
"branding": {
"logo_url": "text",
"primary_color": "text",
"background_color": "text",
"font_family": "text"
}
}{
"branding": {
"logo_url": "text",
"primary_color": "text",
"background_color": "text",
"font_family": "text"
}
}When rendering a surface, the platform merges workspace branding with surface-level branding. Surface-level values take precedence. Changes to workspace branding are audit-logged.
Lifecycle
Created
created
Spec generated and stored
Pending review
pending_review
Surface awaiting field-engineer review before delivery
Delivered
delivered
Sent to patient via channel
Opened
opened
Patient opened the link
Partial
partial
Some fields auto-saved
Completed
completed
All required fields submitted
Expired
expired
TTL exceeded without completion
Archived
archived
Soft-deleted via the DELETE/archive route
Data Flow
Submissions are written to the world model as events:
Source:
surface(distinguishable from EHR, voice, or manual imports)Confidence: Initial confidence level for patient-reported data
Entity: Emitted lifecycle events carry the surface's
entity_id, allowing supported world-model projections and timelines to associate them with that entity
When a patient submits a surface, the platform first commits the surface row as completed. It then schedules surface.submitted world-event emission asynchronously on a best-effort path. Timeline and entity projection updates therefore happen separately and can lag the successful submission response; an emission failure is logged rather than rolling back the committed surface.
An emitted surface event retains source provenance and confidence. Any later entity resolution or typed projection depends on the downstream pipeline for that event shape rather than a universal synchronous rule. Where the private-preview connector review flow is enabled, a configured downstream mutation can stage a separate external write proposal; reviewing that proposal does not change the surface event's confidence.
Patient-Facing Endpoints
Patients access surfaces through HMAC-signed URL tokens. No login or account is required, and each token grants access to one specific surface.
Open a Short Surface Link
Short-URL redirect: /s/f/{surface_id} → /s/{token}.
Generates a fresh HMAC token and issues a 302 redirect so that SMS messages can contain a short, clickable link instead of the long base64-encoded token URL.
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Redirect to full surface URL
Surface not found
Surface expired
Validation Error
GET /s/f/{surface_id} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
No content
Render a Surface
Render a patient-facing surface as HTML.
Token-authenticated — no Bearer auth required. Records a surface.opened lifecycle event on first view.
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Invalid token
Token expired
Validation Error
Rate limited
GET /s/{token} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
No content
Submit a Surface
Submit a patient-facing surface form.
Accepts standard HTML form POST. Writes surface.submitted event with confidence 0.5 (self-reported data).
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
Invalid token
Already submitted
Token expired
Validation Error
Rate limited
POST /s/{token}/submit HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
No content
Save a Surface Field
Auto-save a single field value.
Called by client-side JavaScript on field blur. Writes surface.field_saved event with confidence 0.5.
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
The field value to save
Successful Response
Acknowledgement returned when a field is auto-saved.
savedInvalid token
Payload too large
Validation Error
Rate limited
Save failed
PUT /s/{token}/fields/{key} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 14
{
"value": null
}{
"status": "saved"
}The short-link operation issues a redirect to a fresh signed-token URL and reports missing or expired surfaces separately. Rendering marks the surface as opened. Submission commits the completed surface before scheduling best-effort world-event publication. Field saves update the lifecycle to partial.
Token format: HMAC-SHA256 signed with a configured secret. Contains surface ID and expiration. Validated on every request.
Rate limiting (per IP):
Render: 30 requests/minute
Submit: 10 requests/minute
Auto-save: 30 requests/minute
Field value validation: Individual field values are capped at 10KB to prevent payload abuse.
Rendering: server-side HTML generation for all 14 field types. Mobile-first, XSS-safe. Photo and file uploads use native device capabilities. Signature fields use touch input.
Lifecycle concurrency: each status update is committed against the surface row. Submission locks the row while checking terminal state and marking it completed, which rejects a competing repeat submission. World-event emission is outside that transaction.
When creating a surface via the management API, the response includes the signed token and full url if the token secret is configured.
Gap Scanner Settings
Get Gap Scanner Settings
Update Gap Scanner Settings
Updates require an admin or owner and support partial bodies. Changes to settings are audit-logged.
Surface Analytics
These workspace-scoped operations provide closed-loop optimization data and require viewer-or-higher permissions.
Get Surface Completion Rates
Surface completion rates: overall, by source, time-bucketed trend.
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
301dPossible values: Filter by entity ID
Successful Response
Validation Error
Rate limit exceeded
GET /v1/{workspace_id}/analytics/surfaces/completion-rates HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"ANY_ADDITIONAL_PROPERTY": "anything"
}Get Surface Channel Effectiveness
Per-channel completion rate and average time to complete.
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
30Successful Response
Validation Error
Rate limit exceeded
GET /v1/{workspace_id}/analytics/surfaces/channel-effectiveness HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"ANY_ADDITIONAL_PROPERTY": "anything"
}Get Surface Field Abandonment
Field-level drop-off analysis for abandoned surfaces.
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
30Successful Response
Validation Error
Rate limit exceeded
GET /v1/{workspace_id}/analytics/surfaces/field-abandonment HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"ANY_ADDITIONAL_PROPERTY": "anything"
}Get an Entity's Surface History
Per-entity surface history with preferred channel and completion stats.
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
20Successful Response
Validation Error
Rate limit exceeded
GET /v1/{workspace_id}/analytics/surfaces/entity/{entity_id} HTTP/1.1
Host: platform.api-us.concurrence.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"ANY_ADDITIONAL_PROPERTY": "anything"
}Entity Type
Surfaces introduce the interaction entity type to the world model ontology. Surface lifecycle events (created, delivered, opened, submitted) are tracked as first-class entities with full event sourcing.
Last updated
Was this helpful?

