Authentication
Create an access credential from My PhenoNet → API Access. Send it with every request:
Authorization: AccessKey <access_id>:<secret_key>
Keep the secret key on your server. Do not expose it in browser code or a public repository.
Submit a classification task
POST https://api.phenonet.org/v1/openapi/classification/
Send a JSON request body. image_url must be an HTTPS URL from an image host allowed by the platform.
| Field | Required | Description |
|---|---|---|
image_url |
Yes | HTTPS URL of the image to classify. |
task_name |
No | A name for this task. Defaults to API prediction. |
model_id |
No | Available single-image model ID. The platform default is used when omitted. |
{
"image_url": "https://files.example.org/images/wheat-001.jpg",
"task_name": "wheat-001",
"model_id": "your-model-id"
}
A successful submission returns HTTP 202 and a server-generated task_id:
{
"code": 202,
"msg": "accepted",
"data": {
"task_id": "server-generated-task-id",
"status": "queued",
"status_url": "https://api.phenonet.org/v1/openapi/classification/server-generated-task-id/",
"created_at": "2026-08-03T00:00:00+00:00",
"finished_at": null
}
}
Get task status
GET https://api.phenonet.org/v1/openapi/classification/{task_id}/
The response status is one of queued, running, waiting, succeeded, or failed. When it succeeds, data.result contains the predicted stage and its index.
Python example
import time
import requests
BASE_URL = "https://api.phenonet.org/v1/openapi/classification/"
ACCESS_ID = "your-access-id"
SECRET_KEY = "your-secret-key"
headers = {
"Authorization": f"AccessKey {ACCESS_ID}:{SECRET_KEY}",
}
payload = {
"image_url": "https://files.example.org/images/wheat-001.jpg",
"task_name": "wheat-001",
# "model_id": "your-model-id", # Optional.
}
created = requests.post(BASE_URL, headers=headers, json=payload, timeout=30)
created.raise_for_status()
task = created.json()["data"]
task_id = task["task_id"]
while task["status"] not in {"succeeded", "failed"}:
time.sleep(5)
response = requests.get(f"{BASE_URL}{task_id}/", headers=headers, timeout=30)
response.raise_for_status()
task = response.json()["data"]
if task["status"] == "succeeded":
print(task["result"])
else:
print("Task failed:", task)
Error responses
| HTTP status | Meaning |
|---|---|
400 |
The request body is invalid, contains an unexpected field, or the image URL is not allowed. |
401 |
The access credential is missing or invalid. |
404 |
The task does not exist or does not belong to this credential. |
409 |
Task dispatch is already in progress. |
503 |
The compute service did not accept the task. |
