> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cludo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Make your first Cludo API search call in minutes by setting up authentication, picking your region, and running a sample query against an engine.

export const ApiTokenBuilder = () => {
  const [authType, setAuthType] = useState("basic");
  const [customerId, setCustomerId] = useState("");
  const [engineId, setEngineId] = useState("");
  const [apiKey, setApiKey] = useState("");
  const [copiedHeader, setCopiedHeader] = useState(false);
  const [copiedCurl, setCopiedCurl] = useState(false);
  const siteKeyBase64 = typeof btoa !== "undefined" && customerId && engineId ? btoa(`${customerId}:${engineId}:SearchKey`) : "";
  const basicBase64 = typeof btoa !== "undefined" && customerId && apiKey ? btoa(`${customerId}:${apiKey}`) : "";
  const headerValue = authType === "sitekey" ? siteKeyBase64 ? "SiteKey " + siteKeyBase64 : "" : basicBase64 ? "Basic " + basicBase64 : "";
  const baseUrl = Number(customerId) >= 10000000 ? "https://api-us1.cludo.com" : "https://api.cludo.com";
  const pathCustomerId = customerId.trim() || "<customer-id>";
  const pathEngineId = engineId.trim() || "<engine-id>";
  const authForCurl = authType === "sitekey" ? siteKeyBase64 ? "SiteKey " + siteKeyBase64 : "SiteKey <your-sitekey-token>" : basicBase64 ? "Basic " + basicBase64 : "Basic <your-basic-token>";
  const curlCmd = 'curl -X POST "' + baseUrl + "/api/v4/" + pathCustomerId + "/" + pathEngineId + '/search" \\\n' + '  -H "Authorization: ' + authForCurl + '" \\\n' + '  -H "Content-Type: application/json" \\\n' + "  -d '{\"query\": \"*\", \"page\": 1, \"perPage\": 10}'";
  const copyToClipboard = (text, setter) => {
    if (typeof navigator !== "undefined" && navigator.clipboard) {
      navigator.clipboard.writeText(text).then(() => {
        setter(true);
        setTimeout(() => setter(false), 2000);
      });
    }
  };
  const btnBase = "px-3 py-1.5 rounded-lg text-sm font-medium transition-colors";
  const btnActive = btnBase + " bg-primary text-white";
  const btnInactive = btnBase + " bg-zinc-950/10 dark:bg-white/10 text-zinc-950/80 dark:text-white/80 hover:bg-zinc-950/20 dark:hover:bg-white/20";
  return <div className="p-4 border border-zinc-950/20 dark:border-white/20 rounded-2xl not-prose space-y-4">
      <div className="flex flex-wrap gap-2">
        <button type="button" onClick={() => setAuthType("basic")} className={authType === "basic" ? btnActive : btnInactive}>
          Basic (API Key)
        </button>
        <button type="button" onClick={() => setAuthType("sitekey")} className={authType === "sitekey" ? btnActive : btnInactive}>
          SiteKey (Search)
        </button>
      </div>

      {authType === "sitekey" ? <>
          <div className="grid gap-3 sm:grid-cols-2">
            <label className="block text-sm text-zinc-950/70 dark:text-white/70">
              Customer ID
              <input type="text" value={customerId} onChange={e => setCustomerId(e.target.value)} placeholder="e.g. 10" className="mt-1 w-full rounded-lg border border-zinc-950/20 dark:border-white/20 bg-white dark:bg-zinc-950/50 px-3 py-2 text-sm" />
            </label>
            <label className="block text-sm text-zinc-950/70 dark:text-white/70">
              Engine ID
              <input type="text" value={engineId} onChange={e => setEngineId(e.target.value)} placeholder="e.g. 6" className="mt-1 w-full rounded-lg border border-zinc-950/20 dark:border-white/20 bg-white dark:bg-zinc-950/50 px-3 py-2 text-sm" />
            </label>
          </div>
          <p className="text-xs text-zinc-950/50 dark:text-white/50">
            The token always includes the literal string <code className="font-mono">SearchKey</code> as the third component.
          </p>
        </> : <div className="grid gap-3 sm:grid-cols-2">
          <label className="block text-sm text-zinc-950/70 dark:text-white/70">
            Customer ID
            <input type="text" value={customerId} onChange={e => setCustomerId(e.target.value)} placeholder="e.g. 3" className="mt-1 w-full rounded-lg border border-zinc-950/20 dark:border-white/20 bg-white dark:bg-zinc-950/50 px-3 py-2 text-sm" />
          </label>
          <label className="block text-sm text-zinc-950/70 dark:text-white/70">
            API Key
            <input type="text" value={apiKey} onChange={e => setApiKey(e.target.value)} placeholder="your-api-key" className="mt-1 w-full rounded-lg border border-zinc-950/20 dark:border-white/20 bg-white dark:bg-zinc-950/50 px-3 py-2 text-sm font-mono" />
          </label>
        </div>}

      <div className="space-y-1">
        <p className="text-sm text-zinc-950/70 dark:text-white/70">
          Authorization header value:
        </p>
        <div className="flex items-center gap-2">
          <code className="flex-1 rounded-lg bg-zinc-950/10 dark:bg-white/10 px-3 py-2 text-sm font-mono break-all">
            {headerValue || "—"}
          </code>
          <button type="button" onClick={() => copyToClipboard(headerValue, setCopiedHeader)} disabled={!headerValue} className="shrink-0 rounded-lg border border-zinc-950/20 dark:border-white/20 px-3 py-2 text-sm hover:bg-zinc-950/10 dark:hover:bg-white/10 disabled:opacity-40 disabled:pointer-events-none">
            {copiedHeader ? "Copied!" : "Copy"}
          </button>
        </div>
      </div>

      <div className="space-y-1">
        <p className="text-sm text-zinc-950/70 dark:text-white/70">
          Ready-to-run cURL:
        </p>
        <pre className="rounded-lg bg-zinc-950/10 dark:bg-white/10 p-3 text-xs font-mono overflow-x-auto whitespace-pre-wrap">
          {curlCmd}
        </pre>
        <button type="button" onClick={() => copyToClipboard(curlCmd, setCopiedCurl)} className="rounded-lg border border-zinc-950/20 dark:border-white/20 px-3 py-1.5 text-sm hover:bg-zinc-950/10 dark:hover:bg-white/10">
          {copiedCurl ? "Copied!" : "Copy cURL"}
        </button>
      </div>
    </div>;
};

This guide walks you through making your first search API call using the v4 API.

<Info>
  **Prerequisites:** You need a Cludo account with at least one engine configured. Sign in to [MyCludo](https://my.cludo.com) to get your credentials.
</Info>

## Step 1: Find your region

Your region is determined by your **customer ID**:

| Customer ID      | Region | Base URL                    |
| ---------------- | ------ | --------------------------- |
| Below 10,000,000 | EU     | `https://api.cludo.com`     |
| 10,000,000+      | US     | `https://api-us1.cludo.com` |

## Step 2: Get your credentials

Log in to [MyCludo API settings](https://my.cludo.com/settings/api-settings) and find the following values:

| Value           | Where to find it                         |
| --------------- | ---------------------------------------- |
| **Customer ID** | Dashboard → Account Settings             |
| **Engine ID**   | Dashboard → Engines → select your engine |
| **API Key**     | MyCludo API settings                     |

## Step 3: Build your auth token

Unless an endpoint says otherwise, use **Basic (API Key)** authentication for Cludo API requests:

```bash theme={null}
# Format: base64(customerId:apiKey)
echo -n "3:c8fk2L9mK4pQ" | base64
# Output: MzpjOGZrMkw5bUs0cFE=
```

<Info>
  **SiteKey authentication** is available for public-facing search where you do not want to expose your API key. See the [Authentication guide](/authentication) for SiteKey token format.
</Info>

### Try it: build your token

Use the tool below to generate a Basic or SiteKey authorization header and a ready-to-run cURL command. Basic authentication is the default choice unless you are building a public client-side search integration.

<ApiTokenBuilder />

## Step 4: Make your first search

<Warning>
  Keep Basic API keys private. Use the Basic examples from a trusted backend, script, or local test. For browser code, use SiteKey authentication instead.
</Warning>

<CodeGroup>
  ```bash cURL Basic (EU) theme={null}
  curl -X POST "https://api.cludo.com/api/v4/3/6/search" \
    -H "Authorization: Basic MzpjOGZrMkw5bUs0cFE=" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "*",
      "page": 1,
      "perPage": 10
    }'
  ```

  ```bash cURL Basic (US) theme={null}
  curl -X POST "https://api-us1.cludo.com/api/v4/3/6/search" \
    -H "Authorization: Basic MzpjOGZrMkw5bUs0cFE=" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "*",
      "page": 1,
      "perPage": 10
    }'
  ```

  ```bash cURL SiteKey (EU) theme={null}
  curl -X POST "https://api.cludo.com/api/v4/3/6/search" \
    -H "Authorization: SiteKey Mzo2OlNlYXJjaEtleQ==" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "*",
      "page": 1,
      "perPage": 10
    }'
  ```

  ```python Python theme={null}
  import requests
  import base64

  # Build Basic token: base64(customerId:apiKey)
  token = base64.b64encode(b"3:c8fk2L9mK4pQ").decode()

  # Use https://api-us1.cludo.com for US region
  url = "https://api.cludo.com/api/v4/3/6/search"
  headers = {
      "Authorization": f"Basic {token}",
      "Content-Type": "application/json"
  }
  payload = {
      "query": "*",
      "page": 1,
      "perPage": 10
  }

  response = requests.post(url, json=payload, headers=headers)
  data = response.json()
  print(data)
  ```

  ```typescript TypeScript theme={null}
  // Build Basic token: base64(customerId:apiKey)
  const token = btoa("3:c8fk2L9mK4pQ");

  // Use https://api-us1.cludo.com for US region
  const response = await fetch("https://api.cludo.com/api/v4/3/6/search", {
    method: "POST",
    headers: {
      "Authorization": `Basic ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: "*",
      page: 1,
      perPage: 10,
    }),
  });

  const data = await response.json();
  console.log(data);
  ```

  ```javascript JavaScript theme={null}
  // Build Basic token: base64(customerId:apiKey)
  const token = btoa("3:c8fk2L9mK4pQ");

  // Use https://api-us1.cludo.com for US region
  fetch("https://api.cludo.com/api/v4/3/6/search", {
    method: "POST",
    headers: {
      "Authorization": `Basic ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: "*",
      page: 1,
      perPage: 10,
    }),
  })
    .then((response) => response.json())
    .then((data) => console.log(data));
  ```
</CodeGroup>

## Step 5: Understand the response

```json theme={null}
{
  "typedDocuments": [
    {
      "fields": {
        "Title": "Getting Started Guide",
        "Description": "Learn how to set up Cludo search...",
        "Url": "https://example.com/getting-started"
      },
      "highlight": {
        "Title": "<b>Getting</b> <b>Started</b> Guide"
      },
      "id": "doc_123",
      "score": 15.7
    }
  ],
  "totalDocument": 42,
  "facets": {},
  "banners": [],
  "suggestions": [],
  "fixedQuery": null,
  "queryId": "abc-123-def",
  "generativeAnswerAvailable": true
}
```

| Field                       | Description                                              |
| --------------------------- | -------------------------------------------------------- |
| `typedDocuments`            | Array of search results with field values and highlights |
| `totalDocument`             | Total number of matching documents                       |
| `facets`                    | Facet counts for filtering                               |
| `fixedQuery`                | Spell-corrected query (if applicable)                    |
| `queryId`                   | Unique identifier for this search request                |
| `generativeAnswerAvailable` | Whether AI Chat can answer this query                    |

## What's next?

<CardGroup cols={2}>
  <Card title="Search API (v4)" icon="magnifying-glass" href="/api-reference/v4/search/search">
    Complete search endpoint reference.
  </Card>

  <Card title="Analytics" icon="chart-line" href="/guides/analytics">
    Track searches and clicks.
  </Card>

  <Card title="Pushing Content" icon="upload" href="/guides/pushing-content">
    Push custom content to your search index.
  </Card>

  <Card title="Search Tools" icon="sliders" href="/api-reference/overview#search-tools">
    Manage banners, rankings, quicklinks, and synonyms.
  </Card>
</CardGroup>
