# PlantLab Agent Quickstart

PlantLab's canonical machine interface is the direct API at `https://api.plantlab.ai`.

## Authentication

Send your API key in the `X-API-Key` header.

Do not use `Authorization: Bearer` for the public API.

## Diagnose an image

```bash
curl -X POST https://api.plantlab.ai/diagnose \
  -H "X-API-Key: pl_live_your_api_key" \
  -F "image=@plant.jpg"
```

Notes:
- Request body is `multipart/form-data`
- File field name is `image`
- Supported image formats are `jpg`, `jpeg`, and `png`
- Maximum upload size is 10 MB

## What to store from the response

Store both:
- `request_id` from the JSON body
- `X-Request-ID` from the response header

They should match and are used for:
- feedback submission
- support/debugging correlation
- logging/tracing in your own agent pipeline

## Optional cannabis verification flow

Tomato results do not include verification. For cannabis, add `X-Verify: true` to the diagnose request to request verification. Poll only when the response reports `verification.status` as `pending`.

If the diagnose response includes:

```json
{
  "verification": {
    "status": "pending",
    "verification_id": "123e4567-e89b-12d3-a456-426614174000"
  }
}
```

poll:

```bash
curl -X GET https://api.plantlab.ai/verification/123e4567-e89b-12d3-a456-426614174000 \
  -H "X-API-Key: pl_live_your_api_key"
```

Poll until `status` is no longer `pending`.

## Feedback loop

When a user confirms or corrects a diagnosis, submit feedback with the original `request_id`.

```bash
curl -X POST https://api.plantlab.ai/feedback \
  -H "X-API-Key: pl_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "is_accurate": false
  }'
```

## Reliability score

Every diagnose response has `schema_version` `4.1.0`. Read the top-level `species`, `species_name`, `species_confidence`, `in_scope`, and `routed_reason` fields first. The API returns `cannabis`, `tomato`, or no species. An unknown species has `in_scope: false` and an empty `results` array. Tomato diagnosis is available. A tomato result has a health verdict. An unhealthy tomato result names one cause in `conditions` or `pests`. Spider mites and leaf miners are pests. It has no growth stage and no verification. `species_name` is the scientific name, or `null` when `species` is `null`. `species` can be any ID that matches `^[a-z][a-z0-9_]*$`; known values are `cannabis` and `tomato`. Read each diagnosis in `results`. Each entry has a normalized `bbox` and that plant's diagnosis fields.

`reliability_score` is an optional estimate of result reliability for unhealthy cannabis. It differs from per-condition confidence. Use it to route results for closer review. It does not guarantee correctness.

Use it for routing decisions — for example, escalate to verification (`X-Verify: true`) or warn the user when the score is low.

`reliability_score` is independent from per-class `confidence` (the score for a single class).

The field is optional and is not available for tomato.

## Retry behavior

- On `429`, honor `Retry-After`
- Treat additional response fields as additive and non-breaking within a `schema_version` major
- A `schema_version` major bump (for example, 4.1.0 to 5.0.0) changes the response shape. Read the version before parsing.
- Parse responses defensively: fields may be added over time

## Machine-readable assets

- `/openapi.json`
- `/openapi.yaml`
- `/arazzo.yaml`
- `/llms.txt`

## Species capabilities

Cannabis (`Cannabis sativa`) and tomato (`Solanum lycopersicum`) have live diagnosis. Tomato diagnosis is available. For an unrecognized species, the API returns `species: null`, `in_scope: false`, and `routed_reason: "unknown_species"`. Mixed-species diagnosis in one photo is not supported.

Tomato classes are `early_blight`, `late_blight`, `leaf_mold`, `septoria`, `bacterial_spot`, `leaf_curl_virus`, `mosaic_virus`, `target_spot`, `spotted_wilt_virus`, `magnesium_deficiency`, `nitrogen_deficiency`, `potassium_deficiency`, and the pests `spider_mites` and `leaf_miners`. Healthy is a separate state. An optional `suspected: true` describes a suspected condition, not a healthy result.
