Skip to content
Capabilities

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.

ModeDirectionPatternUse CaseExample Providers
statePullRequest/ResponseDashboards, current status, ambient contextWeather, portfolio, fitness tracker
actionPushRequest/ResponseCreate, update, delete operations with user confirmationTask manager, CRM, messaging
historyPullPaginated listActivity feeds, transaction logs, event timelinesBanking, Git hosting, e-commerce
realtimePush (streaming)SSE streamLive tickers, notifications, collaborative dataStock market, sports scores, chat
webhookPush (event)Event-drivenCalendar changes, new messages, status updatesGoogle 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.

1
Invoke — A surface or system trigger creates an execution request. For actions, user confirmation is collected first. The request is assigned a unique X-Aiffinity-Request-Id.
2
Validate — Aiffinity resolves the user's credentials for your app (OAuth token refresh, API key injection), validates request parameters against the declared input schema, and checks rate limits.
3
Execute — The request is dispatched to your runtimeUrl with the resolved credentials and execution context. Your runtime processes the request and returns a response.
4
Respond — Aiffinity validates the response against the declared output schema, routes valid data to the target surfaces (widgets, Aiven context, daily brief), and records the full execution trace for debugging via the developer console.

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.

Free
100
requests / min
Pro
1,000
requests / min
Enterprise
10,000
requests / min
Limit TypeFreeProEnterprise
State polls / min1001,00010,000
Action executions / min202002,000
History pages / min505005,000
Realtime connections (concurrent)210100
Webhook events / min2002,00020,000
Response timeout10s15s30s
Max response size256 KB1 MB5 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"]
  }
}
FieldDescriptionExample Values
intentSemantic intent of the dataambient_context, actionable_insight, notification, deep_dive
placementPreferred rendering surfaceshome_widgets, daily_brief, aiven_context, connection_profile
preferredComponentsSuggested widget component typesstat_row, sparkline, ranked_list, action_row, progress_bar, cta_banner, meeting_prep

The mapping between capability modes and typical widget components:

ModeCommon ComponentsNotes
statestat_row, sparkline, progress_barSnapshot data maps naturally to gauge-style widgets
actionaction_row, cta_bannerInclude confirmation UI and result feedback
historyranked_list, sparklineTime-series data works well in list and chart formats
realtimesparkline, stat_rowLive-updating numeric displays
webhookmeeting_prep, action_rowEvent-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 CodeHTTP StatusRetryableDescription
INVALID_PARAMS400NoRequest parameters failed validation against the declared schema
AUTH_EXPIRED401YesUser's access token has expired; Aiffinity will attempt a refresh and retry
PERMISSION_DENIED403NoUser lacks required permissions on your service
NOT_FOUND404NoRequested resource does not exist
CONFLICT409NoIdempotency conflict — the request was already processed with different parameters
RATE_LIMITED429YesYour service's own rate limit was exceeded
UPSTREAM_UNAVAILABLE503YesUpstream dependency is temporarily unavailable
INTERNAL_ERROR500YesUnexpected error in your runtime

Retry Semantics

For retryable errors, Aiffinity applies exponential backoff with jitter:

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).