API Documentation v1.0

The Decision Layer API

Infrastructure for deciding what happens next.

Overview

Unconditional Logic is a platform-agnostic decision engine. It evaluates data against configurable rules and returns structured decisions that power your business logic.

Fast Evaluation

Sub-50ms response times for real-time decisions.

Flexible Input

Accept any JSON. Auto-maps to known signals.

Auditable

Every decision logged with full context.

How It Works

01
Send Data
POST any JSON payload to the evaluate endpoint
02
Engine Evaluates
Signals are weighted and scored against thresholds
03
Get Decision
Receive tier (A/B/C), score, and recommended action

Quick Start

Get your first decision in under 5 minutes.

1Get Your API Key

Sign up and generate an API key from your dashboard. Keys are prefixed with sk_live_ for production.

2Create an Engine

POST /api/v1/engines
json
{
  "name": "Lead Qualifier",
  "slug": "lead-qualifier",
  "configJson": {
    "signals": [
      { "key": "email", "weight": 0.1, "evaluation": { "operator": "exists" } },
      { "key": "company_size", "weight": 0.2, "evaluation": { "operator": "gte", "value": 50 } }
    ],
    "thresholds": { "tierA": 0.75, "tierB": 0.45 }
  }
}

3Evaluate Data

POST /api/v1/decisions/evaluate
json
{
  "engineId": "your-engine-uuid",
  "input": {
    "data": {
      "email": "john@acme.com",
      "company_size": 250,
      "job_title": "VP Engineering"
    }
  }
}

4Handle the Response

Response
json
{
  "decisionId": "dec_abc123",
  "tier": "A",
  "score": 0.82,
  "confidence": 0.91,
  "recommendedAction": "book",
  "allowBooking": true,
  "primaryDrivers": ["company_size", "email"]
}

Authentication

Secure your API requests with API keys.

Header Authentication
bash
X-API-Key: sk_live_your_api_key_here

# Or using Bearer token
Authorization: Bearer sk_live_your_api_key_here
PrefixEnvironmentUsage
sk_live_ProductionLive evaluations, real data
sk_test_TestDevelopment, testing

Evaluate

POST/api/v1/decisions/evaluate

The primary evaluation endpoint. Send data, receive a decision.

Request

{
  "engineId": "uuid",
  "input": {
    "data": {
      "email": "john@acme.com",
      "job_title": "VP Engineering",
      "company_name": "Acme Corp",
      "company_size": 500,
      "timeline": "1-3 months",
      "budget_authority": true
    }
  },
  "options": {
    "persist": true,
    "idempotencyKey": "unique-id"
  }
}

Response

{
  "decisionId": "dec_xyz789",
  "tier": "A",
  "score": 0.87,
  "confidence": 0.93,
  "recommendedAction": "book",
  "allowBooking": true,
  "primaryDrivers": [
    "budget_authority",
    "company_size",
    "job_title"
  ],
  "processingTimeMs": 42
}

Tier Classification

A

High quality — approve, book, proceed

B

Medium — review, nurture, conditional

C

Low quality — decline, queue

Public API

No authentication required. For quizzes, forms, and widgets.

POST/api/v1/public/evaluateNo Auth
Request
json
{
  "engineSlug": "wellness-quiz",
  "data": {
    "sleep_score": 65,
    "energy_score": 70,
    "stress_score": 55,
    "age": 35
  },
  "email": "user@example.com"
}
Response
json
{
  "decision": {
    "tier": "B",
    "score": 63,
    "confidence": 85
  },
  "outcome": {
    "action": "recommend_standard",
    "allowBooking": true,
    "drivers": ["stress_score", "sleep_score"]
  }
}

Rate Limited

Public endpoints are limited to 60 requests/minute per IP address.

Engines

Create and manage decision engines.

EndpointDescription
GET /api/v1/enginesList all engines
POST /api/v1/enginesCreate engine
GET /api/v1/engines/:idGet engine details
PUT /api/v1/engines/:idUpdate engine
DELETE /api/v1/engines/:idDelete engine

Engine Configuration

{
  "signals": [
    {
      "key": "job_title",
      "weight": 0.25,
      "evaluation": {
        "operator": "exists",
        "scoreIfMatch": 1,
        "scoreIfMiss": 0
      }
    },
    {
      "key": "company_size",
      "weight": 0.2,
      "evaluation": {
        "operator": "gte",
        "value": 50,
        "scoreIfMatch": 1,
        "scoreIfMiss": 0.3
      }
    }
  ],
  "thresholds": { "tierA": 0.75, "tierB": 0.45 },
  "outcomes": {
    "tierA": { 
      "label": "Qualified",
      "action": "book", 
      "allowBooking": true,
      "webhookUrl": "https://hooks.example.com/...",
      "tags": ["qualified", "enterprise"],
      "priority": "high"
    },
    "tierB": { 
      "label": "Review",
      "action": "review", 
      "allowBooking": true,
      "tags": ["needs-review"]
    },
    "tierC": { 
      "label": "Not Qualified",
      "action": "decline", 
      "allowBooking": false,
      "redirectUrl": "https://example.com/resources"
    }
  }
}

Outcome Configuration

Define what happens when each tier is assigned.

Each tier (A, B, C) can have a rich outcome configuration that defines actions, webhooks, redirects, and CRM integrations. These are returned in the API response and can drive your frontend behavior.

Outcome Fields

FieldTypeDescription
labelstringDisplay name (e.g., "Qualified", "VIP")
actionstringPrimary action type
allowBookingbooleanCan proceed to booking/checkout
messagestringUser-facing message
prioritystringhigh, medium, or low
webhookUrlstringURL to POST decision payload
redirectUrlstringURL to redirect user (supports variables)
tagsstring[]CRM tags to apply
notifyEmailsstring[]Emails to notify
responseDataobjectCustom key-value data in response

Action Types

proceedAllow user to proceed
bookDirect to meeting booking
reviewSend to manual review
nurtureAdd to nurture sequence
recommendShow recommendations
declinePolitely decline
redirectRedirect to URL
webhookTrigger webhook only
queueAdd to general queue

URL Variables

Redirect URLs support variable interpolation:

{{tier}}The assigned tier (A, B, or C)
{{email}}User's email address
{{score}}Normalized score (0-100)
{{decisionId}}Unique decision identifier
https://example.com/thank-you?tier={{tier}}&ref={{decisionId}}

Webhook Payload

When a webhookUrl is configured, this payload is POSTed:

{
  "event": "decision.created",
  "decisionId": "uuid",
  "tier": "A",
  "score": 82,
  "confidence": 91,
  "outcome": {
    "label": "Qualified",
    "action": "book",
    "priority": "high",
    "tags": ["qualified", "enterprise"]
  },
  "person": {
    "email": "john@example.com",
    "name": "John Doe",
    "company": "Acme Corp"
  },
  "engineId": "uuid",
  "engineSlug": "b2b-lead-scorer",
  "timestamp": "2024-12-16T10:30:00Z"
}

Webhooks

Accept data from external form providers.

POST/api/webhooks/intake/:orgSlug/:engineId

Accepts submissions from Typeform, Jotform, Tally, and other form providers. Automatically maps common field formats.

Typeform Format

{
  "form_response": {
    "answers": [
      {
        "field": { "ref": "email" },
        "email": "john@acme.com"
      },
      {
        "field": { "ref": "company" },
        "text": "Acme Corp"
      }
    ]
  }
}

Generic Format

{
  "email": "john@acme.com",
  "firstName": "John",
  "lastName": "Doe",
  "company": "Acme Corp",
  "customField": "value"
}

AI Wizards

Generate engine and quiz configurations with AI.

Engine Wizard

POST /api/ai/engine-wizard

Describe your use case in plain English. Get a complete engine configuration.

{
  "useCase": "Qualify B2B leads for SaaS sales",
  "vertical": "b2b"
}

Quiz Wizard

POST /api/ai/quiz-wizard

Generate complete quiz configurations with questions, themes, and results.

{
  "useCase": "Wellness assessment quiz",
  "vertical": "health",
  "questionCount": 8
}

Signal Catalog

Built-in signals the engine recognizes.

The engine auto-maps common field names to known signals. You can also define custom signals per engine.

Identity

emailfirst_namelast_namephoneagelocation

Authority

job_titleseniority_levelbudget_authoritydecision_maker

Fit

company_namecompany_sizeindustryrevenuetech_stack

Readiness

timelinebudget_rangebuying_stagepain_level

Health

health_scoresleep_scoreenergy_scorestress_score

Ecommerce

cart_valuelifetime_valueorder_countdays_since_purchase

Evaluation Operators

OperatorDescriptionExample
existsField has a value{ "operator": "exists" }
equalsExact match{ "operator": "equals", "value": true }
gteGreater than or equal{ "operator": "gte", "value": 50 }
inValue in array{ "operator": "in", "value": ["A", "B"] }
containsString contains{ "operator": "contains", "value": "VP" }

Error Handling

HTTP status codes and error responses.

CodeMeaningCommon Causes
200SuccessRequest processed
400Bad RequestInvalid input, validation failed
401UnauthorizedMissing or invalid API key
404Not FoundResource doesn't exist
429Too Many RequestsRate limit exceeded
500Server ErrorInternal error
Error Response Format
json
{
  "error": "Validation failed",
  "details": [
    { "path": ["input", "data", "email"], "message": "Invalid email format" }
  ]
}

Rate Limits

Request limits per endpoint type.

Endpoint TypeLimitWindow
Authenticated API1000 requestsPer minute
Public Evaluation60 requestsPer minute (per IP)
AI Wizards20 requestsPer minute
Webhooks100 requestsPer minute (per endpoint)

Ready to build?

Get your API key and start building intelligent decision systems in minutes.