Overview
The Seedlings API lets you track the full lifecycle of seedlings, from sowing seeds indoors to transplanting them into your garden plots. Track germination dates, growing medium, hardening-off schedules, and more.
Lifecycle Stages
Seedlings progress through the following stages:
| Stage | Description |
|---|---|
sown | Seeds have been sown in their starting medium |
germinated | Seeds have sprouted |
growing | Seedlings are actively growing indoors |
hardening | Seedlings are being gradually exposed to outdoor conditions |
transplanted | Seedlings have been moved to their final garden plot |
Endpoints
| Method | Path | Description | Auth Required |
|---|---|---|---|
GET | /seedlings | List your seedlings | Yes |
POST | /seedlings | Create a seedling record | Yes |
GET | /seedlings/:id | Get seedling details | Yes |
PUT | /seedlings/:id | Update a seedling | Yes |
DELETE | /seedlings/:id | Delete a seedling | Yes |
POST | /seedlings/:id/harden | Start hardening-off schedule | Yes |
List Seedlings
Retrieve a paginated list of your seedlings.
GET /seedlings
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 20 | Items per page (max 100) |
stage | string | — | Filter by lifecycle stage |
plant_id | string | — | Filter by plant type |
Response 200 OK
{
"data": [
{
"id": "sdl_a1b2c3d4",
"plant_id": "plant_t0m4t0",
"plant_name": "Tomato",
"variety": "San Marzano",
"stage": "growing",
"sow_date": "2026-02-15T00:00:00Z",
"germinated_date": "2026-02-22T00:00:00Z",
"transplant_date": null,
"medium": "seed_starting_mix",
"location": "grow_light_shelf",
"quantity": 12,
"notes": "Using heat mat for germination",
"created_at": "2026-02-15T09:00:00Z",
"updated_at": "2026-02-22T10:00:00Z"
},
{
"id": "sdl_e5f6g7h8",
"plant_id": "plant_p3pp3r",
"plant_name": "Pepper",
"variety": "Habanero",
"stage": "germinated",
"sow_date": "2026-02-01T00:00:00Z",
"germinated_date": "2026-02-14T00:00:00Z",
"transplant_date": null,
"medium": "peat_pellets",
"location": "south_window",
"quantity": 6,
"notes": null,
"created_at": "2026-02-01T08:00:00Z",
"updated_at": "2026-02-14T12:00:00Z"
}
],
"total": 2,
"page": 1,
"per_page": 20
}
Examples
cURL
curl -X GET "https://garden.gg/api/v1/seedlings?stage=growing" \
-H "Authorization: Bearer gg_live_your_api_key_here"
Python
import requests
headers = {"Authorization": "Bearer gg_live_your_api_key_here"}
response = requests.get(
"https://garden.gg/api/v1/seedlings",
headers=headers,
params={"stage": "growing"},
)
seedlings = response.json()
for s in seedlings["data"]:
print(f"{s['variety']} {s['plant_name']} — {s['stage']} ({s['quantity']} plants)")
Node.js
const response = await fetch(
"https://garden.gg/api/v1/seedlings?stage=growing",
{ headers: { Authorization: "Bearer gg_live_your_api_key_here" } }
);
const { data: seedlings } = await response.json();
seedlings.forEach((s) =>
console.log(`${s.variety} ${s.plant_name} — ${s.stage} (${s.quantity} plants)`)
);
Create Seedling
Create a new seedling record when you sow seeds.
POST /seedlings
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
plant_id | string | Yes | ID from the plant database |
variety | string | No | Specific variety name |
sow_date | string | Yes | Date seeds were sown (RFC 3339) |
medium | string | Yes | Growing medium: seed_starting_mix, peat_pellets, soil, rockwool, vermiculite |
location | string | Yes | Where seedlings are kept: grow_light_shelf, south_window, greenhouse, heat_mat, cold_frame |
quantity | integer | No | Number of seeds sown (default: 1) |
notes | string | No | Additional notes |
Request
{
"plant_id": "plant_t0m4t0",
"variety": "Brandywine",
"sow_date": "2026-03-01T00:00:00Z",
"medium": "seed_starting_mix",
"location": "grow_light_shelf",
"quantity": 8,
"notes": "Using bottom heat, 75°F target"
}
Response 201 Created
{
"id": "sdl_i9j0k1l2",
"plant_id": "plant_t0m4t0",
"plant_name": "Tomato",
"variety": "Brandywine",
"stage": "sown",
"sow_date": "2026-03-01T00:00:00Z",
"germinated_date": null,
"transplant_date": null,
"medium": "seed_starting_mix",
"location": "grow_light_shelf",
"quantity": 8,
"notes": "Using bottom heat, 75°F target",
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-01T10:00:00Z"
}
Examples
cURL
curl -X POST "https://garden.gg/api/v1/seedlings" \
-H "Authorization: Bearer gg_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"plant_id": "plant_t0m4t0",
"variety": "Brandywine",
"sow_date": "2026-03-01T00:00:00Z",
"medium": "seed_starting_mix",
"location": "grow_light_shelf",
"quantity": 8
}'
Python
import requests
response = requests.post(
"https://garden.gg/api/v1/seedlings",
headers={
"Authorization": "Bearer gg_live_your_api_key_here",
"Content-Type": "application/json",
},
json={
"plant_id": "plant_t0m4t0",
"variety": "Brandywine",
"sow_date": "2026-03-01T00:00:00Z",
"medium": "seed_starting_mix",
"location": "grow_light_shelf",
"quantity": 8,
},
)
seedling = response.json()
print(f"Created seedling: {seedling['id']} — stage: {seedling['stage']}")
Node.js
const response = await fetch("https://garden.gg/api/v1/seedlings", {
method: "POST",
headers: {
Authorization: "Bearer gg_live_your_api_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
plant_id: "plant_t0m4t0",
variety: "Brandywine",
sow_date: "2026-03-01T00:00:00Z",
medium: "seed_starting_mix",
location: "grow_light_shelf",
quantity: 8,
}),
});
const seedling = await response.json();
console.log(`Created seedling: ${seedling.id} — stage: ${seedling.stage}`);
Get Seedling
Retrieve details for a single seedling.
GET /seedlings/:id
Response 200 OK
Returns a full seedling object (same structure as in the list response). When the seedling has been through hardening, includes the hardening schedule:
{
"id": "sdl_a1b2c3d4",
"plant_id": "plant_t0m4t0",
"plant_name": "Tomato",
"variety": "San Marzano",
"stage": "hardening",
"sow_date": "2026-02-15T00:00:00Z",
"germinated_date": "2026-02-22T00:00:00Z",
"transplant_date": null,
"medium": "seed_starting_mix",
"location": "grow_light_shelf",
"quantity": 12,
"hardening_schedule": {
"start_date": "2026-04-01T00:00:00Z",
"duration_days": 7,
"current_day": 3
},
"notes": "Using heat mat for germination",
"created_at": "2026-02-15T09:00:00Z",
"updated_at": "2026-04-03T08:00:00Z"
}
Update Seedling
Update a seedling record to track lifecycle changes.
PUT /seedlings/:id
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
variety | string | No | Variety name |
germinated_date | string | No | Date germination observed (RFC 3339) |
transplant_date | string | No | Date transplanted to garden (RFC 3339) |
medium | string | No | Growing medium |
location | string | No | Seedling location |
quantity | integer | No | Updated quantity (e.g., after thinning) |
stage | string | No | Manually set lifecycle stage |
notes | string | No | Additional notes |
Setting germinated_date automatically advances the stage to germinated. Setting transplant_date advances the stage to transplanted.
Request
{
"germinated_date": "2026-03-08T00:00:00Z",
"quantity": 7,
"notes": "7 of 8 seeds germinated. Strong growth."
}
Response 200 OK
Returns the full updated seedling object.
Delete Seedling
Delete a seedling record.
DELETE /seedlings/:id
Response 204 No Content
No response body.
Start Hardening-Off
Initiate a hardening-off schedule for seedlings before transplanting them outdoors. This transitions the seedling to the hardening stage and creates a schedule for gradually increasing outdoor exposure.
POST /seedlings/:id/harden
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
start_date | string | Yes | When to begin hardening (RFC 3339) |
duration_days | integer | No | Number of days for hardening (default: 7) |
Request
{
"start_date": "2026-04-01T00:00:00Z",
"duration_days": 10
}
Response 200 OK
{
"id": "sdl_a1b2c3d4",
"stage": "hardening",
"hardening_schedule": {
"start_date": "2026-04-01T00:00:00Z",
"duration_days": 10,
"current_day": 1
}
}
Examples
cURL
curl -X POST "https://garden.gg/api/v1/seedlings/sdl_a1b2c3d4/harden" \
-H "Authorization: Bearer gg_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"start_date": "2026-04-01T00:00:00Z",
"duration_days": 10
}'
Python
import requests
response = requests.post(
"https://garden.gg/api/v1/seedlings/sdl_a1b2c3d4/harden",
headers={
"Authorization": "Bearer gg_live_your_api_key_here",
"Content-Type": "application/json",
},
json={
"start_date": "2026-04-01T00:00:00Z",
"duration_days": 10,
},
)
result = response.json()
schedule = result["hardening_schedule"]
print(f"Hardening day {schedule['current_day']} of {schedule['duration_days']}")
Node.js
const response = await fetch(
"https://garden.gg/api/v1/seedlings/sdl_a1b2c3d4/harden",
{
method: "POST",
headers: {
Authorization: "Bearer gg_live_your_api_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
start_date: "2026-04-01T00:00:00Z",
duration_days: 10,
}),
}
);
const { hardening_schedule } = await response.json();
console.log(`Hardening day ${hardening_schedule.current_day} of ${hardening_schedule.duration_days}`);
Error Responses
| Scenario | HTTP Status | Error Code |
|---|---|---|
| Seedling not found | 404 | NOT_FOUND |
| Invalid plant_id | 400 | VALIDATION_ERROR |
| Missing required fields | 400 | VALIDATION_ERROR |
| Invalid stage transition | 400 | VALIDATION_ERROR |
| Seedling already transplanted | 400 | VALIDATION_ERROR |
| Not your seedling | 403 | FORBIDDEN |
| Not authenticated | 401 | UNAUTHORIZED |