Brinpage

Brinpage Platform — Quick Start (PHP)

Minimal server-side PHP integration calling Brinpage Platform directly via HTTP. No SDK install, no npm — just env vars + one small client.

Requirements

  • PHP 8.1+ (8.2+ recommended)
  • PHP extension: ext-curl
  • A Brinpage Platform account + license key

1) Add environment variables

Set these in your hosting environment (or a framework .env file).

.env
# Required (server-side only)
BRINPAGE_LICENSE_KEY="bp_xxxx"

# Optional
BRINPAGE_API_BASE="https://platform.brinpage.com"
BRINPAGE_ASK_TIMEOUT_MS=30000

Don’t have a license yet? Create a Platform account and generate your key.

Get your API key

Important: never expose BRINPAGE_LICENSE_KEY to the browser. Keep it server-side (your PHP backend only).

2) Add the Brinpage HTTP client (PHP)

Create a small reusable client (framework-agnostic). Example below assumes a file like src/Brinpage.php.

php
<?php
// src/Brinpage.php

final class Brinpage {
  private string $baseUrl;
  private string $license;
  private int $timeoutMs;

  public function __construct(?string $baseUrl = null, ?string $license = null, ?int $timeoutMs = null) {
    $this->baseUrl = rtrim($baseUrl ?? getenv("BRINPAGE_API_BASE") ?: "https://platform.brinpage.com", "/");
    $this->license = $license ?? getenv("BRINPAGE_LICENSE_KEY") ?: "";
    $this->timeoutMs = $timeoutMs ?? (int)(getenv("BRINPAGE_ASK_TIMEOUT_MS") ?: 30000);

    if ($this->license === "") {
      throw new RuntimeException("Missing BRINPAGE_LICENSE_KEY");
    }
  }

  /**
   * Calls POST /api/sdk/ask
   *
   * @param string $question Required
   * @param array $options Optional fields supported by the API (history, tags, k, minScore, debugEcho, stream, provider, model, etc.)
   * @return array Parsed JSON response
   */
  public function ask(string $question, array $options = []): array {
    $question = trim($question);
    if ($question === "") throw new InvalidArgumentException("Missing 'question'");

    $url = $this->baseUrl . "/api/sdk/ask";

    $body = array_merge(
      [
        "question" => $question,
        // Keep stream false by default (simple HTTP JSON response)
        "stream" => false,
      ],
      $options
    );

    $payload = json_encode($body, JSON_UNESCAPED_SLASHES);
    if ($payload === false) throw new RuntimeException("Failed to encode JSON body");

    $ch = curl_init($url);
    curl_setopt_array($ch, [
      CURLOPT_POST => true,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POSTFIELDS => $payload,
      CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "Accept: application/json",
        "Authorization: Bearer " . $this->license,
      ],
      CURLOPT_CONNECTTIMEOUT_MS => 5000,
      CURLOPT_TIMEOUT_MS => $this->timeoutMs,
    ]);

    $raw = curl_exec($ch);
    $err = curl_error($ch);
    $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($raw === false) {
      throw new RuntimeException("Network error: " . ($err ?: "unknown"));
    }

    $data = json_decode($raw, true);
    if (!is_array($data)) {
      // If response is not JSON, surface a short snippet
      $snippet = mb_substr((string)$raw, 0, 400);
      throw new RuntimeException("Invalid JSON response (HTTP {$status}): " . $snippet);
    }

    if ($status < 200 || $status >= 300) {
      $msg = isset($data["error"]) && is_string($data["error"]) ? $data["error"] : "ask failed ({$status})";
      throw new RuntimeException($msg);
    }

    return $data;
  }

  /**
   * Convenience: extract the main answer text from a successful response.
   */
  public static function pickAnswer(array $res): string {
    foreach (["answer", "text", "message", "output"] as $k) {
      if (isset($res[$k]) && is_string($res[$k]) && trim($res[$k]) !== "") return $res[$k];
    }
    return "";
  }
}
?>

3) Create your own server endpoint

This keeps the Brinpage license key private and gives your frontend a safe URL to call. Below is a minimal JSON endpoint example: POST /api/chat.

php
<?php
// public/api/chat.php (example)
// POST JSON: { "question": "..." }

require_once __DIR__ . "/../../src/Brinpage.php";

header("Content-Type: application/json; charset=utf-8");

if ($_SERVER["REQUEST_METHOD"] !== "POST") {
  http_response_code(405);
  echo json_encode(["ok" => false, "error" => "Method Not Allowed"]);
  exit;
}

$raw = file_get_contents("php://input") ?: "";
$body = json_decode($raw, true);
if (!is_array($body)) {
  http_response_code(400);
  echo json_encode(["ok" => false, "error" => "Invalid JSON body"]);
  exit;
}

$question = isset($body["question"]) && is_string($body["question"]) ? $body["question"] : "";
$tags = isset($body["tags"]) && is_array($body["tags"]) ? $body["tags"] : [];

try {
  $bp = new Brinpage();

  $res = $bp->ask($question, [
    // Optional (examples):
    "tags" => $tags,
    "k" => 6,
    "minScore" => 0.18,
    "debugEcho" => false,
    // You can also pass provider/model overrides if needed.
  ]);

  echo json_encode([
    "ok" => true,
    "answer" => Brinpage::pickAnswer($res),
    "raw" => $res
  ], JSON_UNESCAPED_SLASHES);
} catch (Throwable $e) {
  http_response_code(500);
  echo json_encode(["ok" => false, "error" => $e->getMessage()]);
}
?>

4) Test end-to-end

Once your endpoint is reachable, test it with curl:

bash
curl -X POST https://your-domain.com/api/chat \
  -H "Content-Type: application/json" \
  -d '{"question":"Hello from PHP","tags":["docs"]}'

Common /ask options you’ll actually use

The /ask endpoint supports history, RAG filtering via tags, debug output, streaming, and provider/model overrides.:contentReference[oaicite:2]

  • history: array of chat messages ({ role, content })
  • tags: reduce retrieval scope to specific doc tags
  • k / minScore: retrieval tuning knobs
  • debugEcho: include debug object (retrieval + routing info)
  • provider / model: overrides (optional)
  • stream: SSE mode (advanced; implement when you need token streaming)

Want to switch language/framework? Go back to Installation:

Back to Installation