# Quickstart

> Make your first GeoInfer API call in under 2 minutes.

Source: https://docs.geoinfer.com/quickstart

## 1. Get an API key

Sign in and go to [app.geoinfer.com/en/api](https://app.geoinfer.com/en/api). Create a key. It will start with `geo_`.

<LazyVideo
  title="GeoInfer platform API keys demo"
  description="Short looping demo showing how to create and manage GeoInfer API keys from the platform."
  webmSrc="https://assets.geoinfer.com/docs/platform/geoinfer-platform-api-keys-demo.webm"
  mp4Src="https://assets.geoinfer.com/docs/platform/geoinfer-platform-api-keys-demo.mp4"
  posterSrc="https://assets.geoinfer.com/docs/platform/geoinfer-platform-api-keys-demo-poster.webp"
  width={960}
  height={730}
  duration="PT23S"
  uploadDate="2026-05-21"
  caption="Create an API key from the platform and copy it while it is visible."
/>

## 2. Make your first prediction

Replace `geo_your_api_key_here` and `photo.jpg` with your actual key and image path.

<Tabs items={["cURL", "Python SDK", "Python (requests)", "JavaScript"]}>

<Tab value="cURL">

```bash
curl -X POST "https://api.geoinfer.com/v1/prediction/predict?top_n=5" \
  -H "X-GeoInfer-Key: geo_your_api_key_here" \
  -F "file=@photo.jpg"
```

</Tab>

<Tab value="Python SDK">

Install the [geoinfer SDK](https://pypi.org/project/geoinfer/):

```bash
pip install geoinfer
```

```python
from geoinfer import GeoInfer

client = GeoInfer(api_key="geo_your_api_key_here")
result = client.predictions.predict("photo.jpg")

top = result.prediction.clusters[0]
print(top.location.name, top.center.latitude, top.center.longitude)
```

</Tab>

<Tab value="Python (requests)">

No extra dependencies. Uses the standard `requests` library:

```bash
pip install requests
```

```python
import requests

with open("photo.jpg", "rb") as f:
    response = requests.post(
        "https://api.geoinfer.com/v1/prediction/predict",
        params={"top_n": 5},
        headers={"X-GeoInfer-Key": "geo_your_api_key_here"},
        files={"file": f},
    )

data = response.json()["data"]
top = data["prediction"]["clusters"][0]
print(top["location"]["name"], top["center"]["latitude"], top["center"]["longitude"])
```

</Tab>

<Tab value="JavaScript">

```javascript
const analyzeImage = async (imageFile, apiKey) => {
  const formData = new FormData();
  formData.append('file', imageFile);

  const response = await fetch(
    'https://api.geoinfer.com/v1/prediction/predict?top_n=5',
    {
      method: 'POST',
      headers: { 'X-GeoInfer-Key': apiKey },
      body: formData,
    }
  );

  const result = await response.json();
  return result.data.prediction.clusters;
};
```

</Tab>

</Tabs>

## 3. Read the response

The response shape depends on the model type.

<Tabs items={["Global model", "High accuracy model"]}>

<Tab value="Global model">

Global models return `result_type: "coordinates"` with a ranked list of geographic clusters.

```json
{
  "message_code": "success",
  "data": {
    "prediction": {
      "result_type": "coordinates",
      "clusters": [
        {
          "center": { "latitude": 40.7128, "longitude": -74.006 },
          "location": {
            "name": "New York",
            "admin1": "New York",
            "country_code": "US"
          },
          "radius_km": 15.3
        }
      ],
      "processing_time_ms": 1850
    },
    "prediction_id": "550e8400-e29b-41d4-a716-446655440000",
    "model_id": "global_v4_1",
    "credits_consumed": 1
  }
}
```

`clusters` is sorted by confidence (highest first). `radius_km` indicates the geographic spread of matched points. Lower means tighter precision.

</Tab>

<Tab value="High accuracy model">

High accuracy models return `result_type: "accuracy"` with individual point predictions, **no clusters**. Each entry has a precise coordinate, confidence score, and rank.

```json
{
  "message_code": "success",
  "data": {
    "prediction": {
      "result_type": "accuracy",
      "predictions": [
        {
          "latitude": 43.263,
          "longitude": -2.935,
          "confidence": 0.87,
          "rank": 1,
          "location": {
            "name": "Bilbao",
            "admin1": "Basque Country",
            "admin2": "Bizkaia",
            "country_code": "ES"
          },
          "heading_deg": 245.0
        }
      ],
      "top_prediction": {
        "latitude": 43.263,
        "longitude": -2.935,
        "confidence": 0.87,
        "rank": 1,
        "location": {
          "name": "Bilbao",
          "admin1": "Basque Country",
          "admin2": "Bizkaia",
          "country_code": "ES"
        },
        "heading_deg": 245.0
      },
      "processing_time_ms": 2300
    },
    "prediction_id": "661f9511-f3ac-52e5-b827-557766551111",
    "model_id": "pais_vasco_v2_0",
    "credits_consumed": 3
  }
}
```

`top_prediction` is a convenience field, the same as `predictions[0]`. `heading_deg` is the estimated camera heading in degrees.

</Tab>

</Tabs>

## Choosing a model

The `model_id` parameter controls which model runs. It is optional. **Omit it and your request routes to the current default global model**, which is what we recommend for most integrations.

Model types:

- **Global**: worldwide coverage, 1 credit per call. Returns `clusters`.
- **High Accuracy**: region-specific, higher precision, 3 credits per call. Returns `predictions` (no clusters).
- **Vehicle ID**: 2 credits per call.
- **Property**: 3 credits per call.

If you do want to pin a specific model, call `GET /v1/prediction/models` and take the id from that response rather than hardcoding one. Ids listed there are the models being served right now; each also carries a `status` field. We retire older model versions from time to time, and a retired id is rejected with a `422` naming the model, so reading the id from `/models` (and caching it) means a deprecation never breaks your integration.

`/models` returns the models your account has access to. If a region you need isn't listed, contact [support@geoinfer.com](mailto:support@geoinfer.com) to request access.

<Callout type="info">
  `top_n` accepts values from **1 to 15** (default 5). Values outside that range return a `422`.
</Callout>

## Next steps

- [Authentication](/authentication): learn about API keys and headers
- [Python SDK](/sdks/python): full SDK reference
- [API Reference](/api-reference/predict): complete endpoint documentation