# Quickstart

> Get a free API key and analyse your first image with curl, TypeScript or Python in two minutes.

Rendered page: https://sfwapi.dev/docs/quickstart · All docs in one file: https://sfwapi.dev/llms-full.txt

1. Create a free key in the [console](https://sfwapi.dev/console). The free tier gives you 500 credits a month.
2. Send an image URL:

```bash
curl -X POST https://api.sfwapi.dev/v1/analyze \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/photo.jpg", "policy": {"block_level": 2}}'
```

Or upload a file:

```bash
curl -X POST https://api.sfwapi.dev/v1/analyze \
  -H "Authorization: Bearer sk_live_…" \
  -F "file=@photo.jpg" \
  -F 'policy={"block_level":2,"block_sex_objects":true}'
```

## TypeScript

```ts
import { SfwApi } from '@sfwapi/sdk';

const api = new SfwApi({ apiKey: process.env.SFWAPI_KEY! });
const r = await api.analyzeUrl('https://example.com/photo.jpg', { policy: { block_level: 2, block_sex_objects: true, art: 'same_as_photos' } });

if (r.policy?.blocked) console.log(`blocked at level ${r.policy.matched_level}`);
console.log(r.nudity.level, r.nudity.scores, r.usage.balance);
```

## Python

```python
from sfwapi import SfwApi

api = SfwApi(api_key=os.environ["SFWAPI_KEY"])
r = api.analyze_url("https://example.com/photo.jpg", policy={"block_level": 2, "block_sex_objects": True})
print(r["nudity"]["level"], r["policy"]["blocked"], r["usage"]["balance"])
```

## Reading the answer

- `nudity.level` is the headline: 0 Everyday, 1 Revealing, 2 Implied nudity, 3 Explicit.
- `nudity.scores` are 0–100; above 50 counts. Scores near 50 mean the model is unsure.
- `policy.blocked` is only present when you sent a `policy`.
- `usage.credits` is what this call cost and `usage.balance` what is left.

Keep the key on your server. Browsers and mobile apps should call your backend, not the API directly.
