Skip to main content
This page collects working patterns you can adapt for production integrations. Use these examples as templates, not as copy-paste production code without review. In production, add proper secret handling, retries, timeouts, and structured logging.

Shared environment variables

Use environment variables so the same examples can run in local, staging, and production environments.
export UPPZY_BASE_URL="https://api.uppzy.com/api/v1"
export UPPZY_API_KEY="<YOUR_API_KEY>"
export UPPZY_TENANT_ID="<YOUR_TENANT_ID>"
export UPPZY_SITE_ID="<YOUR_SITE_ID>"

1. Connectivity check with tenant limits

Start every new integration with a simple authenticated read call.
curl --silent --show-error \
  --request GET \
  --url "$UPPZY_BASE_URL/m2m/tenants/$UPPZY_TENANT_ID/limits" \
  --header "X-API-Key: $UPPZY_API_KEY"
Use this request to verify:
  • The API key is valid
  • The environment configuration is correct
  • Your deployment can reach the API

2. Upload a file document

Use file upload when you already have approved content in PDF, Word, or text format.
curl --silent --show-error \
  --request POST \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/documents" \
  --header "X-API-Key: $UPPZY_API_KEY" \
  --form "file=@./docs/return-policy.pdf"
If your integration tracks content versions, log the returned document identifier so you can activate, update, or audit it later.

3. Create a text document

Use text documents when your source content already exists as application-managed text.
curl --silent --show-error \
  --request POST \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/documents/text" \
  --header "X-API-Key: $UPPZY_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "title": "Support Hours",
    "content": "Support is available Monday to Friday between 09:00 and 18:00.",
    "category": "support"
  }'

4. Create a Q&A document

Use Q&A documents for short, deterministic answers to repeated questions.
curl --silent --show-error \
  --request POST \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/documents/qa" \
  --header "X-API-Key: $UPPZY_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "title": "Delivery FAQ",
    "question": "Do you offer same-day delivery?",
    "answer": "Availability depends on location and order timing.",
    "category": "faq"
  }'

5. Send a sync chat request

Use sync chat when the caller expects the answer in the same request cycle.
curl --silent --show-error \
  --request POST \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/chat" \
  --header "X-API-Key: $UPPZY_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "session_id": "web-user-1001",
    "email": "user@example.com",
    "message": "How does the return process work?",
    "ui_locale": "en",
    "response_language": "en"
  }'
Typical response shape:
{
  "session_id": "web-user-1001",
  "request_id": "req_abc123",
  "answer": "Returns are accepted within the published return window.",
  "confidence_score": 92,
  "confidence_level": "high"
}

6. Send an async chat request and poll for completion

Use async chat when you want non-blocking request handling.
REQUEST_ID=$(curl --silent --show-error \
  --request POST \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/chat/async" \
  --header "X-API-Key: $UPPZY_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "session_id": "job-user-2001",
    "message": "Can you summarize your refund policy?"
  }' | jq -r '.request_id')

curl --silent --show-error \
  --request GET \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/chat/requests/$REQUEST_ID" \
  --header "X-API-Key: $UPPZY_API_KEY"
Production polling guidance:
  • Poll on a fixed short interval such as 2-3 seconds
  • Stop when status becomes completed or failed
  • Apply an overall timeout so jobs do not poll forever

7. Submit feedback for a response

Use feedback to send a quality signal after a completed response. Accepted feedback values are good and bad.
curl --silent --show-error \
  --request POST \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/chat/feedback" \
  --header "X-API-Key: $UPPZY_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "session_id": "web-user-1001",
    "request_id": "req_abc123",
    "feedback": "good"
  }'
Send feedback only after the response is completed and only once per evaluation event in your application workflow.

8. Close a session explicitly

Close a session when the business flow is complete and you do not want the conversation to remain open indefinitely.
curl --silent --show-error \
  --request POST \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/chat/session/close" \
  --header "X-API-Key: $UPPZY_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "session_id": "web-user-1001"
  }'

9. Read site statistics

Use site statistics to monitor how your integration performs after rollout.
curl --silent --show-error \
  --request GET \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/statistics" \
  --header "X-API-Key: $UPPZY_API_KEY"

10. Read sessions

Use sessions when you need operational visibility into conversation activity.
curl --silent --show-error \
  --request GET \
  --url "$UPPZY_BASE_URL/m2m/sites/$UPPZY_SITE_ID/sessions" \
  --header "X-API-Key: $UPPZY_API_KEY"

11. Minimal JavaScript client

Use a shared helper for request headers, JSON parsing, and error handling.
const BASE_URL = process.env.UPPZY_BASE_URL || "https://api.uppzy.com/api/v1";
const API_KEY = process.env.UPPZY_API_KEY;

async function uppzy(path, { method = "GET", headers = {}, body } = {}) {
  const response = await fetch(`${BASE_URL}${path}`, {
    method,
    headers: {
      "X-API-Key": API_KEY,
      ...headers,
    },
    body,
  });

  const text = await response.text();
  const data = text ? JSON.parse(text) : null;

  if (!response.ok) {
    const error = new Error(`HTTP ${response.status}`);
    error.status = response.status;
    error.data = data;
    throw error;
  }

  return data;
}

export async function sendSyncChat(siteId, payload) {
  return uppzy(`/m2m/sites/${siteId}/chat`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
}

export async function sendAsyncChat(siteId, payload) {
  return uppzy(`/m2m/sites/${siteId}/chat/async`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
}

export async function getAsyncChatStatus(siteId, requestId) {
  return uppzy(`/m2m/sites/${siteId}/chat/requests/${requestId}`);
}

export async function submitChatFeedback(siteId, payload) {
  return uppzy(`/m2m/sites/${siteId}/chat/feedback`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
}

12. Async polling helper in JavaScript

export async function waitForChat(siteId, requestId, {
  intervalMs = 2500,
  timeoutMs = 30000,
} = {}) {
  const startedAt = Date.now();

  while (true) {
    const result = await getAsyncChatStatus(siteId, requestId);

    if (result.status === "completed") {
      return result;
    }

    if (result.status === "failed") {
      throw new Error(result.error || "Async chat failed");
    }

    if (Date.now() - startedAt > timeoutMs) {
      throw new Error("Async chat polling timed out");
    }

    await new Promise((resolve) => setTimeout(resolve, intervalMs));
  }
}

13. Minimal Python client

import os
import time
import requests

BASE_URL = os.getenv("UPPZY_BASE_URL", "https://api.uppzy.com/api/v1")
API_KEY = os.environ["UPPZY_API_KEY"]


def uppzy(path: str, method: str = "GET", json_body=None, files=None, timeout: int = 30):
    response = requests.request(
        method,
        f"{BASE_URL}{path}",
        headers={"X-API-Key": API_KEY},
        json=json_body,
        files=files,
        timeout=timeout,
    )
    response.raise_for_status()
    return response.json() if response.text else None


def send_sync_chat(site_id: str, payload: dict):
    return uppzy(f"/m2m/sites/{site_id}/chat", method="POST", json_body=payload)


def send_async_chat(site_id: str, payload: dict):
    return uppzy(f"/m2m/sites/{site_id}/chat/async", method="POST", json_body=payload)


def get_async_status(site_id: str, request_id: str):
    return uppzy(f"/m2m/sites/{site_id}/chat/requests/{request_id}")


def wait_for_chat(site_id: str, request_id: str, interval_seconds: float = 2.5, timeout_seconds: int = 30):
    started = time.time()
    while True:
      result = get_async_status(site_id, request_id)
      if result["status"] == "completed":
          return result
      if result["status"] == "failed":
          raise RuntimeError(result.get("error") or "Async chat failed")
      if time.time() - started > timeout_seconds:
          raise TimeoutError("Async chat polling timed out")
      time.sleep(interval_seconds)

14. End-to-end smoke script idea

A minimal smoke flow should:
  1. Validate tenant limits
  2. Upload one small document
  3. Send one sync chat request
  4. Send one async chat request and poll for completion
  5. Submit feedback for a completed request
  6. Read site statistics
Use this as a deploy-time or post-deploy verification sequence in staging before promoting to production.