> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/reference/platform/choosing-the-right-tool.md).

# Choosing the Right Tool

When to use the CLI, Python SDK, or REST API.

Roboflow exposes the same underlying platform through three developer tools. They are not mutually exclusive - most production workflows use all three. This page is a quick decision guide.

## At a glance

|              | CLI                                                    | Python SDK                                              | REST API                                               |
| ------------ | ------------------------------------------------------ | ------------------------------------------------------- | ------------------------------------------------------ |
| **Best for** | Ad-hoc scripts, AI agents, shell automation            | Notebooks, scheduled jobs, Python applications          | Non-Python services, webhooks, edge devices            |
| **Auth**     | `ROBOFLOW_API_KEY` env var or `roboflow login`         | API key passed to `Roboflow(...)` or `ROBOFLOW_API_KEY` | `Authorization: Bearer` header (query param is legacy) |
| **Output**   | Pretty tables by default, `--json` for scripting       | Python dicts and objects                                | JSON                                                   |
| **Install**  | `pip install roboflow`                                 | `pip install roboflow`                                  | None                                                   |
| **Coverage** | Tracks SDK; agent-friendly                             | Same as REST plus convenience helpers                   | Authoritative - every feature ships here first         |
| **Errors**   | Exit codes (0 / 1 / 2 / 3) + JSON error body on stderr | Python exceptions                                       | HTTP status codes + JSON error body                    |

## When to use the CLI

Use the CLI when you want to do something **once or as a step in a shell pipeline**. The output formats and exit codes are designed for scripting and AI agents.

Concretely:

* You're prototyping and want to see results quickly without writing Python.
* You want to pipe Roboflow operations into other tools (`roboflow project list --json | jq …`).
* You're using an AI coding agent (Claude Code, Cursor) - the CLI's structured JSON output and stable exit codes are easier for an agent to consume than a Python REPL.
* You're writing a `Makefile`, GitHub Action, or shell script that uploads images, kicks off training, or downloads a dataset.

See [CLI](/reference/platform/cli.md).

## When to use the Python SDK

Use the SDK when you're already in Python and want **typed objects, idiomatic helpers, and cross-call state**. The SDK is a thin wrapper around the REST API but it adds:

* `Workspace` / `Project` / `Version` / `Model` objects with discoverable methods.
* Concurrent uploads (`upload_dataset(num_workers=10)`).
* Prediction visualization helpers (when the full `roboflow` package is installed - not `roboflow-slim`).
* Active-learning loops that combine inference and upload.
* Direct access to vision-events ingestion.

Concretely:

* You're in a Jupyter notebook iterating on a dataset.
* You're building a Python service that uploads, trains, or runs inference on demand.
* You need to chain operations (upload → train → wait for ready → predict).
* You're integrating Roboflow into an existing Python app.

See [Python SDK](/reference/platform/python-sdk.md).

## When to use the REST API

Use the REST API when **you're not in Python**, when you need to call from an environment that can't install Python packages (a browser, a Cloudflare Worker, an embedded device, a Lambda with a tiny zipfile), or when you want to consume Roboflow from a webhook.

Concretely:

* You're building a JavaScript / TypeScript / Go / Rust client.
* You're posting events from a webcam or sensor that runs custom firmware.
* You need to integrate with Zapier / n8n / a no-code automation tool.
* A specific feature ships in the REST API before it lands in the SDK.

See [REST API](/reference/platform/rest-api.md).

## Mixing tools

In practice teams use all three:

* **CI/CD** uses the CLI to upload datasets and kick off training.
* **A Python data pipeline** uses the SDK to react to training results and tune model versions.
* **A production app** uses the REST API to run inference and post events.

The same workspace and API key authenticate against all three, so credentials don't multiply.

## Inference is special

For running a trained model on an image or video, you have additional choices beyond these three. Hosted inference runs against the [Roboflow Serverless Hosted API](https://docs.roboflow.com/deployment/roboflow-cloud/serverless-api) at `serverless.roboflow.com`; for higher throughput or on-prem use cases see [Roboflow Inference](https://docs.roboflow.com/deployment/self-hosted/self-hosted) (self-hosted) and [Dedicated Deployments](https://docs.roboflow.com/deployment/roboflow-cloud/dedicated-deployments) (managed GPU machines).

The CLI's `infer` command, the SDK's `model.predict()`, and a direct REST call to the inference URL are all paths to the same underlying inference engines.

Authentication for inference requests also differs from the platform REST API. When you call an inference URL directly, send your API key as an `Authorization: Bearer` header; the header keeps the key out of URLs and server logs. Passing the key as an `api_key` query parameter or body field is the legacy channel: it still works on every server version, but is not recommended for new code. When using `inference-sdk`, set the transport once on the client instead of building headers yourself: see [API key transport](/reference/inference/inference-sdk/configuration.md#api-key-transport).
