Capabilities Reference
Modes Overview
Every capability on the Aiffinity platform uses one of five execution modes. The mode determines how Aiffinity communicates with your runtime, what schemas are required, and what guarantees are provided.
| Mode | Direction | Pattern | Use Case | Example Providers |
|---|---|---|---|---|
| state | Pull | Request/Response | Dashboards, current status, ambient context | Weather, portfolio, fitness tracker |
| action | Push | Request/Response | Create, update, delete operations with user confirmation | Task manager, CRM, messaging |
| history | Pull | Paginated list | Activity feeds, transaction logs, event timelines | Banking, Git hosting, e-commerce |
| realtime | Push (streaming) | SSE stream | Live tickers, notifications, collaborative data | Stock market, sports scores, chat |
| webhook | Push (event) | Event-driven | Calendar changes, new messages, status updates | Google Calendar, Slack, GitHub |
State
state State Capability
Returns a point-in-time snapshot. Aiffinity polls your runtimeUrl at the configured refreshInterval (in seconds). The response is cached and served to surfaces until the next refresh. Ideal for dashboards, status displays, and ambient context widgets.
Request Schema
// Aiffinity sends to your runtime:
POST /capabilities/current_weather/execute
Authorization: Bearer <user_access_token>
X-Aiffinity-Request-Id: req_abc123
X-Aiffinity-User-Id: usr_def456
{
"capability": "current_weather",
"mode": "state",
"params": {
"location": "Zurich, CH"
},
"context": {
"userId": "usr_def456",
"installId": "inst_789",
"locale": "en-US",
"timezone": "Europe/Zurich"
}
}
Response Schema
{
"status": "ok",
"data": {
"location": "Zurich, CH",
"temperature_c": 18,
"condition": "sunny",
"humidity_pct": 45,
"wind_speed_kmh": 12
},
"ttl": 900,
"metadata": {
"source": "weatherapi.com",
"fetchedAt": "2026-04-04T10:30:00Z"
}
}
Action
action Action Capability
Executes a side-effect (create, update, delete). Actions always require user confirmation in the Aiffinity UI before execution. The platform enforces idempotency via the X-Aiffinity-Idempotency-Key header. Best for creating records, sending messages, or triggering workflows.
Request Schema
POST /capabilities/create_task/execute
Authorization: Bearer <user_access_token>
X-Aiffinity-Request-Id: req_abc123
X-Aiffinity-Idempotency-Key: idem_xyz789
{
"capability": "create_task",
"mode": "action",
"input": {
"title": "Review Q2 report",
"due_date": "2026-04-10",
"priority": "high",
"assignee": "[email protected]"
},
"context": {
"userId": "usr_def456",
"confirmationId": "conf_abc123"
}
}
Response Schema
{
"status": "ok",
"result": {
"taskId": "task_12345",
"url": "https://app.taskservice.com/tasks/12345",
"created": true
},
"message": "Task 'Review Q2 report' created and assigned to [email protected]"
}
History
history History Capability
Returns a time-ordered, cursor-paginated list of past events or records. The cursor is opaque to Aiffinity; your runtime controls pagination logic. Used for activity feeds, transaction logs, and conversation history.
Request Schema
POST /capabilities/recent_transactions/execute
Authorization: Bearer <user_access_token>
X-Aiffinity-Request-Id: req_abc123
{
"capability": "recent_transactions",
"mode": "history",
"params": {
"limit": 20,
"cursor": "txn_98765",
"direction": "backward"
},
"context": {
"userId": "usr_def456",
"installId": "inst_789",
"locale": "en-US",
"timezone": "Europe/Zurich"
}
}
Response Schema
{
"status": "ok",
"items": [
{
"id": "txn_98764",
"amount": -42.50,
"currency": "USD",
"merchant": "Coffee Shop",
"category": "food_and_drink",
"date": "2026-04-03T09:15:00Z"
},
{
"id": "txn_98763",
"amount": -120.00,
"currency": "USD",
"merchant": "Electronics Store",
"category": "shopping",
"date": "2026-04-02T14:22:00Z"
}
],
"cursor": {
"next": "txn_98762",
"hasMore": true
},
"totalCount": 1847
}
Realtime
realtime Realtime Capability
Establishes a Server-Sent Events (SSE) connection. Aiffinity maintains the connection and distributes events to subscribed surfaces. Your runtime must send heartbeat events at the configured interval to keep the connection alive. Ideal for live tickers, notifications, and collaborative data.
SSE Stream Format
// Aiffinity opens:
GET /capabilities/price_ticker/stream
Authorization: Bearer <user_access_token>
Accept: text/event-stream
X-Aiffinity-Request-Id: req_abc123
// Your runtime responds:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
event: data
data: {"symbol":"AAPL","price":198.42,"change":1.23,"timestamp":"2026-04-04T14:30:00Z"}
event: data
data: {"symbol":"GOOGL","price":178.91,"change":-0.45,"timestamp":"2026-04-04T14:30:01Z"}
event: heartbeat
data: {"ts":"2026-04-04T14:30:30Z"}
event: data
data: {"symbol":"AAPL","price":198.55,"change":1.36,"timestamp":"2026-04-04T14:31:00Z"}
Heartbeat events must be sent at least every heartbeatInterval seconds (configured in the capability template). If Aiffinity receives no events for 2x the heartbeat interval, the connection is considered stale and will be re-established.
Webhook
webhook Webhook Capability
Your service pushes events to Aiffinity when state changes. Register event types with schemas during package creation. Aiffinity validates incoming payloads and routes them to the appropriate surfaces and processing pipelines. Best for integrations where polling is impractical.
Inbound Webhook Payload
// Your service sends to Aiffinity:
POST https://api.aiffinity.me/v1/providers/runtime/webhook
Authorization: Bearer <app_access_token>
X-Signature-256: sha256=abc123def456...
Content-Type: application/json
{
"event": "calendar_event_changed",
"action": "updated",
"timestamp": "2026-04-04T10:00:00Z",
"userId": "usr_def456",
"data": {
"eventId": "evt_123",
"title": "Team standup",
"start": "2026-04-05T09:00:00Z",
"end": "2026-04-05T09:15:00Z",
"location": "Zoom",
"attendees": ["[email protected]", "[email protected]"]
}
}
Aiffinity Acknowledgement
{
"status": "accepted",
"event_id": "evt_aiffinity_abc123",
"processed_at": "2026-04-04T10:00:01Z"
}
Execution Lifecycle
Every capability execution follows the same four-phase lifecycle, regardless of mode.
X-Aiffinity-Request-Id.runtimeUrl with the resolved credentials and execution context. Your runtime processes the request and returns a response.If any phase fails, the error is captured in the execution trace and a capability.failed webhook event is emitted (if subscribed). For retryable errors, the platform applies exponential backoff automatically.
Rate Limits
Rate limits are enforced per app, per user, per capability. Limits vary by your account tier. When a limit is exceeded, the platform returns 429 Too Many Requests with a Retry-After header.
| Limit Type | Free | Pro | Enterprise |
|---|---|---|---|
| State polls / min | 100 | 1,000 | 10,000 |
| Action executions / min | 20 | 200 | 2,000 |
| History pages / min | 50 | 500 | 5,000 |
| Realtime connections (concurrent) | 2 | 10 | 100 |
| Webhook events / min | 200 | 2,000 | 20,000 |
| Response timeout | 10s | 15s | 30s |
| Max response size | 256 KB | 1 MB | 5 MB |
Rate limit headers are included in every response:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1743782460
Surface Guidance
Surface guidance tells Aiffinity how your capability's data should be rendered. While Aiffinity owns all consumer UI rendering, you can provide hints about which widget components best represent your data.
{
"surfaceGuidance": {
"intent": "ambient_context",
"placement": ["home_widgets", "daily_brief", "aiven_context"],
"preferredComponents": ["stat_row", "sparkline", "progress_bar"]
}
}
| Field | Description | Example Values |
|---|---|---|
intent | Semantic intent of the data | ambient_context, actionable_insight, notification, deep_dive |
placement | Preferred rendering surfaces | home_widgets, daily_brief, aiven_context, connection_profile |
preferredComponents | Suggested widget component types | stat_row, sparkline, ranked_list, action_row, progress_bar, cta_banner, meeting_prep |
The mapping between capability modes and typical widget components:
| Mode | Common Components | Notes |
|---|---|---|
state | stat_row, sparkline, progress_bar | Snapshot data maps naturally to gauge-style widgets |
action | action_row, cta_banner | Include confirmation UI and result feedback |
history | ranked_list, sparkline | Time-series data works well in list and chart formats |
realtime | sparkline, stat_row | Live-updating numeric displays |
webhook | meeting_prep, action_row | Event-driven updates trigger contextual widgets |
See the Widget Components page for the full component catalog with visual examples.
Error Handling
When your runtime encounters an error, return the standard error envelope. Aiffinity uses the code field to determine retry behavior and user-facing messaging.
// Error response from your runtime
{
"status": "error",
"error": {
"code": "UPSTREAM_UNAVAILABLE",
"message": "Weather API is temporarily unavailable",
"retryable": true,
"retryAfter": 60
}
}
Error Codes
| Error Code | HTTP Status | Retryable | Description |
|---|---|---|---|
INVALID_PARAMS | 400 | No | Request parameters failed validation against the declared schema |
AUTH_EXPIRED | 401 | Yes | User's access token has expired; Aiffinity will attempt a refresh and retry |
PERMISSION_DENIED | 403 | No | User lacks required permissions on your service |
NOT_FOUND | 404 | No | Requested resource does not exist |
CONFLICT | 409 | No | Idempotency conflict — the request was already processed with different parameters |
RATE_LIMITED | 429 | Yes | Your service's own rate limit was exceeded |
UPSTREAM_UNAVAILABLE | 503 | Yes | Upstream dependency is temporarily unavailable |
INTERNAL_ERROR | 500 | Yes | Unexpected error in your runtime |
Retry Semantics
For retryable errors, Aiffinity applies exponential backoff with jitter:
- Base delay: 1 second
- Maximum delay: 5 minutes
- Maximum retries: 3
- If
retryAfteris specified in the error response (in seconds), it takes precedence over the default backoff schedule
For AUTH_EXPIRED errors specifically, Aiffinity attempts to refresh the user's OAuth token before retrying. If the refresh fails, the error is surfaced to the user as a re-authentication prompt.
Best practice: Always include a human-readable message in your error responses. Aiffinity may display this message to users in certain contexts (e.g. failed action confirmations).