Skip to main content

    API Reference

    Integrate Keypra into your applications via the REST API. Execute workflows, compositions, skills, personas, and the Judge & Sanitiser services programmatically. Available exclusively on the Expert plan.

    ⚠️Expert tier required
    The Keypra REST API is available exclusively on the Expert plan. Builder and Free accounts cannot create or use API keys. Existing Builder keys will stop working after 6 May 2026.
    ℹ️Interactive Playground Available
    For an interactive API playground, tutorials, and SDK examples, visit the Developer Hub .

    The Keypra API lets you programmatically list and execute your workflows, compositions, skills, and personas, manage context cards, and call the Judge and Sanitiser services. Use it to integrate AI orchestration into your own applications, pipelines, or automations.

    Authentication

    All API requests are authenticated using the X-API-Key header with an mdi_ prefixed key.

    Authentication Header
    curl -X GET "https://keypra.com/api/public/v1/workflows" \
      -H "X-API-Key: mdi_your_api_key_here" \
      -H "Content-Type: application/json"

    API Key Management

    • Create keys: Navigate to Settings → API Access to generate new keys
    • Key prefix: All keys start with mdi_ for easy identification
    • Granular scopes: Assign specific permissions per key (see Scopes below)
    • Rotation: Rotate keys periodically for security
    • Revocation: Instantly revoke compromised keys from Settings

    Scopes

    API keys use granular scopes to control access. Assign only the scopes each integration needs:

    ScopeDescription
    read:workflowList and view workflows
    execute:workflowExecute workflows
    read:compositionList and view compositions
    execute:compositionExecute compositions
    read:skillList and view skills
    execute:skillExecute skills
    read:personaList and view persona context cards
    execute:personaExecute personas with user input
    api:context-cardsRead and write context cards (list, get, create, update, delete)
    api:judgeScore prompts or outputs against a rubric
    api:sanitiserScan text for PII or policy violations
    api:expertWildcard for all Expert-tier endpoints (judge, sanitiser, context-cards)

    Rate Limits

    API requests are rate-limited per API key. Limits below apply to all Expert-tier accounts:

    TierRequests/MinuteRequests/Day
    Expert12020,000

    Response Headers

    Every API response includes the following headers:

    X-API-Version: v2026-02-17
    X-RateLimit-Limit: 60
    X-RateLimit-Remaining: 58
    X-RateLimit-Reset: 1739836800
    X-Credits-Remaining: 4250

    Endpoints

    Base URL: https://keypra.com/api/public/v1

    Workflows

    GET
    /workflowsList your workflows
    POST
    /workflows/:id/executeExecute a workflow

    Compositions

    GET
    /compositionsList saved compositions
    POST
    /compositions/:id/executeExecute a composition

    Skills

    GET
    /skillsList available skills
    POST
    /skills/:id/executeExecute a skill

    Personas

    GET
    /personasList persona context cards
    POST
    /personas/:id/executeExecute persona with user input

    Context Cards

    GET
    /context-cardsList your context cards
    POST
    /context-cardsCreate a context card
    PATCH
    /context-cards/:idUpdate a context card
    DELETE
    /context-cards/:idDelete a context card

    Judge

    POST
    /judge/runScore a prompt or output against a rubric

    Sanitiser

    POST
    /sanitiser/scanScan text for PII / policy violations

    Example Requests

    List Workflows

    curl -X GET "https://keypra.com/api/public/v1/workflows" \
      -H "X-API-Key: mdi_your_api_key_here"

    Execute a Workflow

    curl -X POST "https://keypra.com/api/public/v1/workflows/WORKFLOW_ID/execute" \
      -H "X-API-Key: mdi_your_api_key_here" \
      -H "Content-Type: application/json" \
      -d '{
        "inputs": {
          "topic": "Machine Learning",
          "audience": "intermediate"
        }
      }'

    Execute a Persona

    curl -X POST "https://keypra.com/api/public/v1/personas/PERSONA_ID/execute" \
      -H "X-API-Key: mdi_your_api_key_here" \
      -H "Content-Type: application/json" \
      -d '{
        "input": "Review this email draft for tone and clarity...",
        "model": "google/gemini-2.5-flash"
      }'

    List Compositions

    curl -X GET "https://keypra.com/api/public/v1/compositions" \
      -H "X-API-Key: mdi_your_api_key_here"

    Error Handling

    The API returns JSON error responses with a machine-readable error code:

    {
      "error": {
        "code": "RATE_LIMIT_EXCEEDED",
        "message": "Rate limit exceeded. Please retry after 60 seconds.",
        "retry_after": 60
      }
    }

    Error Codes

    400
    INVALID_REQUESTInvalid request body or parameters
    401
    UNAUTHORIZEDMissing or invalid X-API-Key header
    401
    API_EXPERT_ONLYAccount is not on the Expert plan — API access is gated to Expert
    403
    INSUFFICIENT_SCOPEAPI key lacks required scope for this action
    404
    RESOURCE_NOT_FOUNDWorkflow, composition, skill, or persona not found
    429
    RATE_LIMIT_EXCEEDEDRate limit exceeded, check X-RateLimit-Reset header
    402
    INSUFFICIENT_CREDITSNot enough credits to complete this request
    500
    INTERNAL_ERRORInternal server error, please retry

    SDKs & Libraries

    Official SDKs are coming soon. In the meantime, use the REST API directly or wrap it with a simple client:

    TypeScript Client Example
    class KeypraClient {
      private apiKey: string;
      private baseUrl = 'https://keypra.com/api/public/v1';
    
      constructor(apiKey: string) {
        this.apiKey = apiKey;
      }
    
      private async request<T>(path: string, options?: RequestInit): Promise<T> {
        const response = await fetch(`${this.baseUrl}${path}`, {
          ...options,
          headers: {
            'X-API-Key': this.apiKey,
            'Content-Type': 'application/json',
            ...options?.headers,
          },
        });
        
        if (!response.ok) {
          const error = await response.json();
          throw new Error(`API Error: ${error.error?.code || response.status}`);
        }
        
        return response.json();
      }
    
      async listWorkflows() {
        return this.request('/workflows');
      }
    
      async executeWorkflow(workflowId: string, inputs: Record<string, any>) {
        return this.request(`/workflows/${workflowId}/execute`, {
          method: 'POST',
          body: JSON.stringify({ inputs }),
        });
      }
    
      async listPersonas() {
        return this.request('/personas');
      }
    
      async executePersona(personaId: string, input: string, model?: string) {
        return this.request(`/personas/${personaId}/execute`, {
          method: 'POST',
          body: JSON.stringify({ input, model }),
        });
      }
    }
    
    // Usage
    const client = new KeypraClient('mdi_your_api_key_here');
    const workflows = await client.listWorkflows();
    const result = await client.executePersona('persona-id', 'Review this draft...');
    💡Developer Hub
    Visit the Developer Hub for interactive playground, step-by-step tutorials, and more code examples.

    Partner integrations (Master Server Auth)

    Approved partners (e.g. the Tabley Skill Bridge) can call Keypra without managing per-user API keys. Authentication is handled by the Master Server with a partner key (prefix mpk_). Keys are stored as SHA-256 hashes; the plaintext is shown once at issue. Lookup uses an RPC plus a timing-safe delay to resist enumeration.

    • Partner keys are issued by Keypra staff from the admin console; users do not generate them.
    • Partner calls inherit your org's policies — EU-only models, Strict BYOK, Sanitiser rules.
    • Use the same scopes table above; partner keys can be scoped to a single product surface.

    BYOK and the API

    • If your account or org has an active BYOK key, AI calls through the gateway use it and bypass Keypra credit metering.
    • If the BYOK key fails (BYOK_KEY_INVALID), the request hard-fails with HTTP 502 — Keypra will never silently fall back to a shared model.
    • To force gateway routing for a specific call, pass { "use_byok": false } in the request body where supported.