REFERENCE DOCUMENTATION · v1.0

API Documentation

Everything you need to integrate ZPL's mathematical equilibrium engine into your application.

BASE URL https://web-production-5ece2.up.railway.app

Quick Start

Get your first ZPL result in under 60 seconds. Choose your language below and copy-paste the example to get started.

PYTHON
import requests

# Your API key (get one at zero-point-logic.io)
API_KEY = "zpl_your_api_key_here"
BASE_URL = "https://web-production-5ece2.up.railway.app"

def compute_zpl(bias, N=7, samples=10000):
    """Compute ZPL p_output for given parameters."""
    headers = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
    payload = {
        "bias": bias,
        "N": N,
        "samples": samples
    }
    response = requests.post(
        f"{BASE_URL}/samples",
        json=payload,
        headers=headers
    )
    response.raise_for_status()
    return response.json()

# Test with biased input — ZPL always returns ~0.5
result = compute_zpl(bias=0.9, N=7, samples=50000)
print(f"Input bias: 0.9 → p_output: {result['p_output']:.4f}")
# Output: Input bias: 0.9 → p_output: 0.5001
JAVASCRIPT
const API_KEY = "zpl_your_api_key_here";
const BASE_URL = "https://web-production-5ece2.up.railway.app";

async function computeZPL(bias, N = 7, samples = 10000) {
  const response = await fetch(`${BASE_URL}/samples`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": API_KEY
    },
    body: JSON.stringify({ bias, N, samples })
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }

  return response.json();
}

// Test: biased input always returns ~0.5
computeZPL(0.75, 9, 20000)
  .then(result => console.log(`p_output: ${result.p_output}`))
  .catch(err => console.error(err));
CURL
# Basic request — compute p_output
curl -X POST "https://web-production-5ece2.up.railway.app/samples" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: zpl_your_api_key_here" \
  -d '{
    "bias": 0.85,
    "N": 7,
    "samples": 10000
  }'

# Response:
# {
#   "p_output": 0.5002,
#   "bias": 0.85,
#   "N": 7,
#   "samples": 10000,
#   "elapsed_ms": 42
# }

# Health check (no auth required)
curl "https://web-production-5ece2.up.railway.app/health"

API Reference

All endpoints are served over HTTPS. The API accepts and returns JSON.

POST /samples

Compute the ZPL output probability (p_output) for a given input bias, matrix size N, and number of Monte Carlo samples. This is the primary endpoint for all ZPL computations.

REQUEST BODY
{
  "bias": 0.85,
  "N": 7,
  "samples": 10000
}
RESPONSE
{
  "p_output": 0.5003,
  "bias": 0.85,
  "N": 7,
  "samples": 10000,
  "elapsed_ms": 38,
  "version": "1.0"
}
PARAMETERS
PARAMETERTYPEREQUIREDRANGEDESCRIPTION
bias float Required 0.0 – 1.0 Input probability of a 1-bit. 0.5 = fair, 0.9 = highly biased.
N integer Required 3 – 25 Matrix dimension. Odd values recommended (3, 5, 7, 9…).
samples integer Optional 100 – 50,000 Number of Monte Carlo samples. Default: 10,000. Higher = more precise.
GET /sweep

Run a full bias sweep from 0.0 to 1.0 in configurable steps for a fixed N. Returns an array of (bias, p_output) pairs showing ZPL's equilibrium property across all bias values.

QUERY PARAMETERS
GET /sweep?N=7&steps=20&samples=5000
RESPONSE
{
  "N": 7,
  "steps": 20,
  "results": [
    {"bias":0.0, "p_output":0.4998},
    {"bias":0.05, "p_output":0.5001},
    // ... 18 more rows
    {"bias":1.0, "p_output":0.4997}
  ]
}
GET /health

Health check endpoint. No authentication required. Returns API status, uptime, and version information. Use this to verify connectivity before making computation requests.

RESPONSE
{
  "status": "ok",
  "version": "1.0",
  "uptime_seconds": 86400,
  "engine": "ZPL-Core",
  "timestamp": "2026-03-29T12:00:00Z"
}
This endpoint is exempt from rate limits and does not require an API key. Ideal for monitoring and health checks in production deployments.
POST /compute

Alias for /samples. Accepts identical request body and returns identical response structure. Provided for semantic clarity — use whichever endpoint name matches your mental model.

Note: /compute and /samples are functionally identical. Both count against the same rate limit quota.

Authentication

All computation endpoints require a valid API key passed in the request header. Keys are tied to your subscription plan and enforce rate limits.

X-API-Key Header

HTTP HEADER
POST /samples HTTP/1.1
Host: web-production-5ece2.up.railway.app
X-API-Key: zpl_live_abc123xyz456def789
Content-Type: application/json
Security Warning: Never expose your API key in client-side JavaScript or public repositories. Use environment variables or a server-side proxy for browser applications.
PLAN LIMITS
PLANREQUESTS/MONTHMAX SAMPLESMAX NSWEEP ACCESS
FREE1,00010,00015No
BASIC10,00025,00021Yes
PRO50,00050,00025Yes
ENTERPRISEUnlimited50,00025Yes

Error Codes

The API uses standard HTTP status codes. Error responses always include a JSON body with a message field.

400
Bad Request
Invalid parameters. Check that bias is 0.0–1.0, N is 3–25, and samples is 100–50,000.
401
Unauthorized
Missing or invalid API key. Ensure X-API-Key header is present and correct.
429
Too Many Requests
Rate limit exceeded. Check your plan limits. The Retry-After header indicates when to retry.
500
Server Error
Internal error. These are rare — if persistent, contact support with the request ID.
ERROR RESPONSE FORMAT
{
  "error": "Bad Request",
  "message": "Parameter 'bias' must be between 0.0 and 1.0",
  "status": 400,
  "request_id": "req_abc123"
}

Rate Limits

Rate limits are enforced per API key on a rolling monthly window. Exceeding limits returns a 429 with a Retry-After header.

PLANMONTHLY REQUESTSBURST (per min)CONCURRENTPRICE
FREE1,000101$0
BASIC10,000603$9/mo
PRO50,00020010$29/mo
ENTERPRISEUnlimited1,00050Custom

Language Examples

Drop-in classes for the most common use cases. Copy, paste, configure your API key.

PYTHON — ZPL Client Class
import requests
from dataclasses import dataclass
from typing import List, Dict

@dataclass
class ZPLResult:
    p_output: float
    bias: float
    N: int
    samples: int
    elapsed_ms: int

class ZPLClient:
    """Official ZPL Python client."""
    BASE_URL = "https://web-production-5ece2.up.railway.app"

    def __init__(self, api_key: str):
        self.session = requests.Session()
        self.session.headers.update({
            "X-API-Key": api_key,
            "Content-Type": "application/json"
        })

    def compute(self, bias: float, N: int = 7, samples: int = 10000) -> ZPLResult:
        r = self.session.post(f"{self.BASE_URL}/samples",
            json={"bias": bias, "N": N, "samples": samples})
        r.raise_for_status()
        data = r.json()
        return ZPLResult(**{k: data[k] for k in ZPLResult.__dataclass_fields__})

    def sweep(self, N: int = 7, steps: int = 20) -> List[Dict]:
        r = self.session.get(f"{self.BASE_URL}/sweep",
            params={"N": N, "steps": steps})
        r.raise_for_status()
        return r.json()["results"]

    def health(self) -> Dict:
        return self.session.get(f"{self.BASE_URL}/health").json()

# Usage
zpl = ZPLClient("zpl_your_key")
res = zpl.compute(bias=0.9, N=9, samples=50000)
print(f"p_output = {res.p_output:.4f}")  # ≈ 0.5000
JAVASCRIPT — ZPL Client Class
class ZPLClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = "https://web-production-5ece2.up.railway.app";
  }

  async compute(bias, N = 7, samples = 10000) {
    const res = await fetch(`${this.baseUrl}/samples`, {
      method: "POST",
      headers: { "Content-Type": "application/json", "X-API-Key": this.apiKey },
      body: JSON.stringify({ bias, N, samples })
    });
    if (!res.ok) throw new Error(`ZPL Error ${res.status}`);
    return res.json();
  }

  async sweep(N = 7, steps = 20) {
    const res = await fetch(`${this.baseUrl}/sweep?N=${N}&steps=${steps}`, {
      headers: { "X-API-Key": this.apiKey }
    });
    return res.json();
  }

  async health() {
    return (await fetch(`${this.baseUrl}/health`)).json();
  }
}

// Usage
const zpl = new ZPLClient("zpl_your_key");
zpl.compute(0.8, 7, 10000).then(r => console.log(`p_output: ${r.p_output}`));
UNITY C# — ZPL Integration
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class ZPLClient : MonoBehaviour
{
    private const string API_KEY = "zpl_your_key";
    private const string BASE_URL = "https://web-production-5ece2.up.railway.app";

    [System.Serializable]
    public class ZPLRequest {
        public float bias;
        public int N;
        public int samples;
    }

    [System.Serializable]
    public class ZPLResponse {
        public float p_output;
        public float bias;
        public int N;
        public int elapsed_ms;
    }

    public IEnumerator ComputeZPL(float bias, int N, System.Action<ZPLResponse> callback)
    {
        var req = new ZPLRequest { bias = bias, N = N, samples = 10000 };
        string json = JsonUtility.ToJson(req);
        using var www = new UnityWebRequest(BASE_URL + "/samples", "POST");
        www.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(json));
        www.downloadHandler = new DownloadHandlerBuffer();
        www.SetRequestHeader("Content-Type", "application/json");
        www.SetRequestHeader("X-API-Key", API_KEY);
        yield return www.SendWebRequest();
        if (www.result == UnityWebRequest.Result.Success) {
            var resp = JsonUtility.FromJson<ZPLResponse>(www.downloadHandler.text);
            callback?.Invoke(resp);
        }
    }
}