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

# SDKs & tools

> There are no official client SDKs yet. Use the OpenAPI spec to generate a client or drive the API from Postman, cURL, or Python today.

## No official SDKs yet — use the OpenAPI spec

Synthpop does **not** publish official client SDKs at this time. Official SDKs are
on the roadmap. In the meantime, the API ships a machine-readable **OpenAPI
specification** that every modern tool understands — so you can import it into an
API client, generate a typed client in your language, or call the endpoints
directly with cURL or `requests`.

<Note>
  The API is a small, stable REST surface — eight endpoints over a single Task
  resource. A generated or hand-written client is a short exercise. See the
  [API reference](/api-reference/introduction) for the full contract.
</Note>

## Get the OpenAPI spec

You can obtain the spec two ways:

* **Live from the API** (always current for that environment):
  * Production: `https://app.synthpop.ai/public/v1/openapi.json`
  * Staging: `https://stage.synthpop.ai/public/v1/openapi.json`
* **Rendered reference:** browse and try every endpoint in the
  [API reference](/api-reference/introduction) tab, which is generated from the
  same spec.

```bash Download the production spec theme={null}
curl -s https://app.synthpop.ai/public/v1/openapi.json -o synthpop-openapi.json
```

<Note>
  The spec declares two absolute servers — `https://app.synthpop.ai/public/v1`
  (production) and `https://stage.synthpop.ai/public/v1` (staging). Most
  generators pick the first by default; select the staging server when you want
  to target staging.
</Note>

## Import into an API client

<Tabs>
  <Tab title="Postman">
    In Postman: **Import → File** (or paste the spec URL). Postman generates a
    collection with every endpoint. Add an `Authorization: Bearer <token>` header
    (from [`POST /auth/get_token`](/authentication)) at the collection level so it
    applies to all requests, and set the base URL variable to your environment
    host.
  </Tab>

  <Tab title="Insomnia">
    In Insomnia: **Create → Import** and point it at the spec file or URL. It
    creates a request for each endpoint. Set a `bearerToken`/base-URL environment
    variable and reference it from the requests' auth and URL.
  </Tab>
</Tabs>

## Generate a client

Any OpenAPI code generator works. With
[`openapi-generator`](https://openapi-generator.tech/):

```bash theme={null}
# Generate a Python client from the downloaded spec
openapi-generator-cli generate \
  -i synthpop-openapi.json \
  -g python \
  -o ./synthpop-client
```

Swap `-g python` for `typescript-axios`, `go`, `java`, or any other supported
generator. Point the generated client's base URL at your environment host (see
the warning above), and feed it a bearer token obtained from
`POST /auth/get_token`.

<Info>
  Generated clients are unofficial and unsupported by Synthpop — treat them as a
  convenience, and pin the generator version so regenerating the spec doesn't
  silently reshape your client.
</Info>

## Call it directly

You don't need any tooling to use the API. Every call is a plain HTTPS request
with a bearer token. These are the two patterns used throughout this
documentation.

<CodeGroup>
  ```bash cURL theme={null}
  BASE_URL="https://app.synthpop.ai/public/v1"

  # 1. Exchange your api_secret for a bearer token.
  TOKEN=$(curl -s -X POST "$BASE_URL/auth/get_token" \
    -H "Content-Type: application/json" \
    -d "{\"api_secret\": \"$SYNTHPOP_API_SECRET\"}" | jq -r .token)

  # 2. Call any endpoint with the token.
  curl -s "$BASE_URL/task/list" \
    -H "Authorization: Bearer $TOKEN"
  ```

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

  BASE_URL = "https://app.synthpop.ai/public/v1"


  class SynthpopClient:
      """A minimal hand-written client over the public API."""

      def __init__(self, base_url: str, api_secret: str):
          self.base_url = base_url
          self._token = self._get_token(api_secret)

      def _get_token(self, api_secret: str) -> str:
          resp = requests.post(
              f"{self.base_url}/auth/get_token",
              json={"api_secret": api_secret},
          )
          resp.raise_for_status()
          return resp.json()["token"]

      @property
      def _headers(self) -> dict:
          return {"Authorization": f"Bearer {self._token}"}

      def list_tasks(self, **params) -> dict:
          resp = requests.get(
              f"{self.base_url}/task/list",
              headers=self._headers,
              params=params,
          )
          resp.raise_for_status()
          return resp.json()


  client = SynthpopClient(BASE_URL, os.environ["SYNTHPOP_API_SECRET"])
  print(client.list_tasks())
  ```
</CodeGroup>

<Tip>
  The bearer token is valid for 365 days (about a year). Cache it and re-exchange your
  `api_secret` only when the token expires, rather than calling
  `POST /auth/get_token` on every request. See
  [Authentication](/authentication).
</Tip>

## Related

<CardGroup cols={2}>
  <Card title="API reference" icon="code" href="/api-reference/introduction">
    Every endpoint, request shape, and response field — with a live playground.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/quickstart">
    From an `api_secret` to your first result in five steps.
  </Card>

  <Card title="Authentication" icon="key" href="/authentication">
    How to obtain and use a bearer token.
  </Card>

  <Card title="Versioning" icon="tag" href="/reference/versioning">
    Why the `v1` in the base URL is the version that matters.
  </Card>
</CardGroup>
