Documentation

Private betaGuarani AI is in private beta. The packages, endpoints and flags below are the v1 beta interface and may change before general availability. Access tokens are issued to provisioned workspaces.

Overview

Guarani AI gives every release a single, explained verdict. It has three modules that work on their own or together.

Verify
AI code review and architecture compliance on every pull request: semantic review, performance budgets, API contract checks and generated tests.
Mesh
An OpenAI-compatible gateway in front of Azure OpenAI, Amazon Bedrock, Google Vertex AI and open-weight models on dedicated GPUs, with routing policies, failover, caching and per-team budgets.
Mobile CI
End-to-end UI and regression suites on real Android and iOS devices, started from your existing pipelines.

Concepts

Workspace
Your organization's tenant: members, access tokens, policies, data region and retention.
Project
One repository connected to a workspace, configured by its guarani.yml.
Profile
A named set of checks and gates, for example pull-request or release.
Run
One execution of a profile, a Mesh query or a mobile suite, with its logs and artifacts.
Verdict
The result of a run: pass, advisory or fail, with the findings that explain it.

Quickstart

Three commands take a repository from nothing to a first verdict. You need a workspace access token, issued when your trial workspace is provisioned.

terminal
npm i -g @guarani-ai/cli
guarani login
guarani verify --repo acme/core-api --profile pull-request

guarani login stores the token in your operating system keychain. In CI, set GUARANI_TOKEN instead.

Install the CLI

The CLI is distributed on npm as @guarani-ai/cli. It requires Node.js 20 or later and runs on Linux, macOS and Windows.

terminal
npm i -g @guarani-ai/cli
guarani --version

Configuration

guarani init creates guarani.yml at the root of the repository. It declares profiles, performance budgets, the Mesh policy and providers, and the mobile suites and devices.

guarani.yml
# guarani.yml
version: 1
project: acme/core-api

profiles:
  pull-request:
    checks: [architecture, contracts, performance]
    tests: generate-missing
    block_on: [fail]
  release:
    checks: [architecture, contracts, performance, tests]
    mobile: checkout
    block_on: [fail, advisory]

budgets:
  latency_p95_ms: 450
  memory_mb: 512

mesh:
  policy: balanced  # latency | balanced | cost
  providers: [azure-openai, amazon-bedrock, google-vertex-ai, gpu-open-weight]
  residency: us     # us | eu
  daily_budget_usd:
    payments: 66
    search: 60

mobile:
  suites:
    checkout:
      framework: maestro
      path: e2e/checkout
  devices: [pixel-8, iphone-15, galaxy-s24]
  retries: 1

Profiles are selected with --profile. block_on sets which verdicts fail the check in your pipeline.

CLI reference

Every command accepts --help. Commands exit with code 1 when the verdict matches the profile's block_on list.

CommandWhat it does
guarani loginAuthenticate with a workspace access token.
guarani initCreate guarani.yml from the languages, services and API contracts detected in the repository.
guarani verifyRun a verification for a repository and profile, and report the verdict.
guarani mesh statsShow traffic share, latency and spend by provider or team for a time window.
guarani mesh routeExplain which provider and region a sample request would be routed to, without sending it.
guarani mobile runRun a mobile suite on real devices and attach video, logs and network traces.
guarani runs listList recent runs with their status and verdict.
FlagDescription
--repo <owner/name>Repository to run against. Defaults to the Git remote of the current directory.
--profile <name>Profile from guarani.yml, for example pull-request or release.
--report <github|gitlab|markdown>Publish the result as a GitHub check, a GitLab merge request note, or Markdown on stdout.
--jsonPrint machine-readable JSON instead of the human-readable log.
terminal
# Install the CLI (Node.js 20 or later)
npm i -g @guarani-ai/cli

# Authenticate with your workspace access token
guarani login

# Create guarani.yml for this repository
guarani init

# Run the release profile and print a JSON report
guarani verify --repo acme/core-api --profile release --json

GitHub Actions

Add a workflow that runs on pull_request. Store the workspace token as the repository secret GUARANI_TOKEN. The checks: write permission lets the CLI post the verdict as a check.

.github/workflows/guarani.yml
name: guarani
on: pull_request

permissions:
  contents: read
  checks: write
  pull-requests: write

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm i -g @guarani-ai/cli
      - run: guarani verify --profile pull-request --report github
        env:
          GUARANI_TOKEN: ${{ secrets.GUARANI_TOKEN }}

GitLab CI

Add a job that runs on merge request pipelines. Store the workspace token as a masked CI/CD variable named GUARANI_TOKEN.

.gitlab-ci.yml
guarani-verify:
  stage: test
  image: node:20
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - npm i -g @guarani-ai/cli
    - guarani verify --profile pull-request --report gitlab
  # GUARANI_TOKEN is a masked CI/CD variable in the project settings

REST API

Base URL: https://api.guarani-llc.com/v1. Authenticate with Authorization: Bearer <token>. Requests and responses are JSON.

MethodPathPurpose
POST/v1/verificationsStart a verification for a repository, ref and profile.
GET/v1/verifications/{id}Get the status, verdict and findings of a verification.
POST/v1/mesh/chat/completionsOpenAI-compatible chat completions, routed by Mesh.
GET/v1/mesh/usage?group_by=teamToken usage and spend, grouped by team, provider or model.
POST/v1/mobile/runsStart a mobile suite on a set of devices.
GET/v1/mobile/runs/{id}/artifactsList the video, device logs and network traces of a run.

Start a verification

POST /v1/verifications
curl https://api.guarani-llc.com/v1/verifications \
  -H "Authorization: Bearer $GUARANI_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c1d9e2a-1842-release" \
  -d '{"repo": "acme/core-api", "ref": "refs/pull/1842/head", "profile": "release"}'

Response 202 Accepted:

application/json
{
  "id": "ver_01JB7Q4M2XK8",
  "status": "queued",
  "repo": "acme/core-api",
  "ref": "refs/pull/1842/head",
  "profile": "release",
  "created_at": "2026-10-25T14:02:11Z",
  "links": {
    "self": "https://api.guarani-llc.com/v1/verifications/ver_01JB7Q4M2XK8"
  }
}

Mesh chat completions

The Mesh endpoint follows the OpenAI chat completions format, so existing OpenAI client libraries work by changing the base URL to https://api.guarani-llc.com/v1/mesh. Use "model": "auto" to let the policy choose, or name a model your workspace allows. metadata.team attributes spend to a team budget.

POST /v1/mesh/chat/completions
curl https://api.guarani-llc.com/v1/mesh/chat/completions \
  -H "Authorization: Bearer $GUARANI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model": "auto", "messages": [{"role": "user", "content": "Summarize this diff"}], "metadata": {"team": "payments"}}'

Errors

Errors use standard HTTP status codes and a JSON body with a stable type, a readable message and the request_id to quote when you contact support.

application/json
{
  "error": {
    "type": "invalid_request",
    "message": "Profile 'release' is not defined in guarani.yml.",
    "request_id": "req_7Q2M9X4K1B"
  }
}

Rate limits and retries

Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset. A 429 response includes Retry-After in seconds. Send an Idempotency-Key header on POST requests: a retry with the same key within 24 hours returns the original response instead of starting a second run.

Webhooks

Workspaces can subscribe to verification.completed, mobile.run.completed and mesh.budget.threshold. Each delivery is signed with HMAC-SHA256 using your webhook secret, in the Guarani-Signature header (t=<timestamp>,v1=<signature>, computed over <timestamp>.<raw body>). Reject deliveries older than five minutes.

verify_signature.py
import hashlib
import hmac

def is_valid(secret: bytes, body: bytes, header: str) -> bool:
    # header looks like: t=1761400931,v1=5f2b...
    parts = dict(item.split("=", 1) for item in header.split(","))
    signed = parts["t"].encode() + b"." + body
    expected = hmac.new(secret, signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])

SDKs

Typed SDKs wrap the same REST endpoints, with retries, idempotency keys and pagination handled for you.

TypeScript

terminal
npm i @guarani-ai/sdk
verify.ts
import { Guarani } from "@guarani-ai/sdk";

const guarani = new Guarani({ token: process.env.GUARANI_TOKEN });

const run = await guarani.verifications.create({
  repo: "acme/core-api",
  ref: "refs/pull/1842/head",
  profile: "release",
});

// Polls until the verdict is ready
const result = await guarani.verifications.wait(run.id);
console.log(result.verdict, result.findings.length);

Python

terminal
pip install guarani-ai
verify.py
import os
from guarani_ai import Guarani

client = Guarani(token=os.environ["GUARANI_TOKEN"])

run = client.verifications.create(
    repo="acme/core-api",
    ref="refs/pull/1842/head",
    profile="release",
)

# Polls until the verdict is ready
result = client.verifications.wait(run.id)
print(result.verdict, len(result.findings))

Support

Write to sylvain@guarani-llc.com. Include the request_id from any error response and the run ID when a run is involved. During the private beta, provisioned workspaces get answers from the engineer who builds the product.