API Reference

Approvals API

Review and decide on AI-proposed actions via the API

The Approvals API allows you to retrieve pending approvals and make decisions on AI-proposed actions such as sending replies or executing platform actions.

Overview

When Keva's AI proposes an action that requires human review (based on your autonomy settings), it creates an approval request. Use this API to:

  • List pending approvals
  • View approval details
  • Approve or reject proposed actions

Endpoints

MethodEndpointDescription
GET/api/approvalsList approvals
PATCH/api/approvals/:idDecide on an approval

List Approvals

Retrieve approvals filtered by status.

GET /api/approvals

Query Parameters

ParameterTypeDefaultDescription
statusstringpendingFilter: pending, approved, rejected

Example Request

curl "https://app.keva.support/api/approvals?status=pending" \
  -H "Authorization: Bearer keva_live_your_api_key"

Example Response

[
  {
    "id": "apr_abc123",
    "ticketId": "tkt_xyz789",
    "actionType": "send_reply",
    "status": "pending",
    "expiresAt": "2024-01-15T18:30:00Z",
    "createdAt": "2024-01-15T10:30:00Z",
    "decidedAt": null,
    "ticketSubject": "Cannot access my account",
    "customerEmail": "customer@example.com",
    "customerName": "John Doe",
    "draft": "Hi John,\n\nI understand you're having trouble accessing your account...",
    "model": "claude-sonnet-4-20250514",
    "classification": {
      "category": "account_access",
      "sentiment": "frustrated",
      "urgency": "high"
    },
    "reasoning": {
      "context": "Customer locked out of account",
      "approach": "Provide password reset instructions",
      "confidence": 0.92
    }
  },
  {
    "id": "apr_def456",
    "ticketId": "tkt_abc123",
    "actionType": "platform_action",
    "status": "pending",
    "platform": "shopify",
    "actionId": "refund_order",
    "description": "Refund order #12345 for $49.99",
    "riskLevel": "medium",
    "diff": [
      {"field": "order_status", "before": "fulfilled", "after": "refunded"},
      {"field": "refund_amount", "before": "$0.00", "after": "$49.99"}
    ]
  }
]

Approval Types

Send Reply (send_reply)

AI-drafted response to send to the customer.

FieldDescription
draftThe proposed message text
modelAI model used for generation
classificationTicket classification (category, sentiment, urgency)
reasoningAI's reasoning for the response

Platform Action (platform_action)

Proposed action on a connected platform.

FieldDescription
platformPlatform name (e.g., shopify, stripe)
actionIdAction identifier
descriptionHuman-readable description
riskLevellow, medium, high
diffBefore/after changes

Browser Action (browser_action)

Proposed browser automation task.

FieldDescription
siteUrlTarget website URL
descriptionTask description
previewUrlScreenshot preview URL

Action Plan (action_plan)

Multi-step action sequence.

FieldDescription
planIdPlan identifier
planTitlePlan title
planDescriptionOverall description
planStepsArray of steps to execute
overallRiskCombined risk assessment

Decide on Approval

Approve or reject a pending approval.

PATCH /api/approvals/:id

Request Body

FieldTypeRequiredDescription
decisionstringYesapproved or rejected
rejectionReasonstringNoReason for rejection

Example: Approve

curl -X PATCH https://app.keva.support/api/approvals/apr_abc123 \
  -H "Authorization: Bearer keva_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"decision": "approved"}'

Example: Reject

curl -X PATCH https://app.keva.support/api/approvals/apr_abc123 \
  -H "Authorization: Bearer keva_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "decision": "rejected",
    "rejectionReason": "Tone is too informal for this customer"
  }'

Response

{
  "id": "apr_abc123",
  "status": "approved"
}

Expiration

Approvals have an expiration time (typically 24 hours). Expired approvals:

  • Are automatically filtered from the pending list
  • Cannot be approved or rejected
  • Result in no action being taken

Race Condition Handling

The API uses atomic database operations to prevent race conditions. If two users try to decide on the same approval simultaneously:

  • Only one decision succeeds
  • The second request receives a 404 error
  • The approval's final state reflects only the first decision