DevPlace Code Farm Game API
The Code Farm endpoints: reading state and leaderboards, planting and harvesting, plots and upgrades, watering and raiding a neighbour, fertilizer, daily bonus, quests, perks, prestige, mastery, legacy and the infrastructure, defense and cosmetic sinks.
Endpoint reference
The Code Farm is a cooperative idle game. Each member owns a farm of plots, plants software projects that build over real time, harvests them for coins and XP, upgrades their CI tier for faster builds, and waters other members' growing builds to speed them up and earn coins.
Refactoring (prestige) costs a dynamic coin fee that grows with prestige and current wealth; the fees fill a community treasury from which active low-balance farms can claim a weekly grant.
All endpoints negotiate HTML or JSON. POST bodies are form encoded (application/x-www-form-urlencoded). Every own-farm action returns {"ok": true, "farm": {...}}
- the full updated farm state - so a client can refresh without a second request; the two
neighbour actions (water, steal) return the neighbour's farm as {"farm": {...}}, and a successful steal adds stole_coins. An invalid action (not enough coins, wrong plot state, a protected harvest, an active cooldown) returns HTTP 400 as {"error": {"status": 400, "message": "..."}}; an unknown farm username is 404. Reading your own farm state also runs lazy owner effects: the CI Bot legacy upgrade auto-harvests ready builds, and any due Defense upkeep is charged. The complete rules, formulas, and an automated client are on the Code Farm guide.
GET /game - Code Farm page
The player's own farm: HUD, plot grid, shop, and leaderboard.
Minimal role: Member
Sample response
{
"ok": true,
"farm": {
"coins": 50,
"level": 1,
"plots": []
}
}
GET /game/state - Farm state
The signed-in player's full farm state as JSON. Reading it auto-collects ready builds (with the CI Bot legacy upgrade, reported as autoharvested/autoharvestcoins/autoharvest_xp) and charges any due Defense upkeep.
Minimal role: Member
Sample response
{
"ok": true,
"farm": {
"coins": 50,
"level": 1,
"ci_tier": 1,
"plot_count": 4,
"prestige": 0,
"stars": 0,
"refactor_cost": 20000,
"plots": [
{
"slot": 0,
"state": "empty",
"raided_fraction": 0.0
}
],
"daily_streak_reset": false,
"contract_boost_seconds_remaining": 0,
"auto_harvested": 0,
"steal_max_per_victim_per_day": 3,
"defense_downgrade_available": false,
"crops": [
{
"key": "python",
"name": "Python Script",
"cost": 15,
"reward_coins": 36,
"grow_seconds": 120,
"locked": false,
"market_state": "normal"
}
]
}
}
GET /game/leaderboard - Farm leaderboard
Top 25 farmers on a chosen board: score (default), prestige, harvests (this week), raids (avg coins per successful raid over 30 days, min 3 raids), timetokernel, fair_play, or era (current Era only, empty when none is running). Cached about 15 seconds.
Minimal role: Public
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
board | query | string | no | Leaderboard board key. |
Sample response
{
"entries": [
{
"rank": 1,
"username": "alice",
"level": 4,
"xp": 600,
"coins": 240,
"total_harvests": 52,
"prestige": 1,
"score": 6120,
"title": "The Architect"
}
]
}
GET /game/farm/{username} - View a farm
Another player's farm, with per-plot canwater/cansteal flags computed for the viewer.
Minimal role: Public
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
username | path | string | yes | Farm owner's username. |
Sample response
{
"farm": {
"owner_username": "alice",
"is_owner": false,
"plots": []
}
}
POST /game/plant - Plant a crop
Plant a crop in an empty plot. Costs the crop's live coin price (the cost field in the farm state's crops list).
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slot | form | integer | yes | Plot slot index, 0-based. |
crop | form | string | yes | Crop key. |
Sample response
{
"ok": true,
"farm": {
"coins": 35
}
}
POST /game/harvest - Harvest a build
Harvest a finished (state ready) build for coins and XP.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slot | form | integer | yes | Plot slot index, 0-based. |
Sample response
{
"ok": true,
"farm": {
"coins": 86
}
}
POST /game/buy-plot - Buy a plot
Unlock a new plot (up to 12). Cost starts at 100 coins and doubles per extra plot; the exact price is the farm state's nextplotcost.
Minimal role: Member
Sample response
{
"ok": true,
"farm": {
"plot_count": 5
}
}
POST /game/upgrade - Upgrade CI
Upgrade the farm CI tier for faster builds (up to tier 5); the exact price is the farm state's cinextcost.
Minimal role: Member
Sample response
{
"ok": true,
"farm": {
"ci_tier": 2
}
}
POST /game/farm/{username}/water - Water a build
Water another player's growing build to cut 8% off its build time; pays the visitor 6 coins scaled by their own prestige and Tech Debt Payoff multiplier, plus 3 XP. Once per visitor per build, 3 waterings per build total.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
username | path | string | yes | Farm owner's username. |
slot | form | integer | yes | Plot slot index, 0-based. |
Sample response
{
"farm": {
"owner_username": "alice"
}
}
POST /game/farm/{username}/steal - Steal a build
Raid another player's ready build once its protection window has passed. You take a share of the build's realized coin value (half by default, less against defended owners - the plot's stealcoins field is the exact payout) and the owner keeps and can still harvest the remainder; the plot records the share taken as raidedfraction. Limited to once per hour per neighbour and 3 raids per victim per day; a fully stripped build reports steal_reason stripped, and Security Fortress builds are immune.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
username | path | string | yes | Farm owner's username. |
slot | form | integer | yes | Plot slot index, 0-based. |
Sample response
{
"farm": {
"owner_username": "alice"
},
"stole_coins": 18
}
POST /game/fertilize - Fertilize a build
Spend coins to halve a growing build's remaining time (the plot's fertilize_cost field is the exact price). The price is computed from the exact value this build will pay out - including the golden multiplier and any active contract, Underdog, or Canary upside - so fertilizing is a pure time-skip and never a profit, on any build, at any prestige, with any combination of boosts.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slot | form | integer | yes | Plot slot index, 0-based. |
Sample response
{
"ok": true,
"farm": {
"coins": 12
}
}
POST /game/daily - Claim daily bonus
Claim the once-per-UTC-day coin bonus; consecutive days grow a streak (20 coins on day one up to 92 from day seven on), scaled by your own prestige and Tech Debt Payoff multiplier. A lapsed streak resets to day one - the farm state's dailystreakreset flag and daily_reward already reflect that.
Minimal role: Member
Sample response
{
"ok": true,
"farm": {
"streak": 3,
"coins": 94
}
}
POST /game/perk - Upgrade a perk
Upgrade a permanent perk with coins: yield (+5% harvest coins), growth (+4% build speed), discount (-3% planting cost), or xp (+5% harvest XP) per level. Perks reset on refactor.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
perk | form | string | yes | Perk key. |
Sample response
{
"ok": true,
"farm": {
"coins": 0
}
}
POST /game/quests/claim - Claim a quest
Claim a completed daily quest by its kind, or (with scope=weekly, requires the Legacy Contracts Mastery upgrade) the weekly contract, which pays Stars plus a 48-hour +20% coin boost instead of coins.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
quest | form | string | yes | Quest kind. |
scope | form | string | no | daily (default) or weekly. |
Sample response
{
"ok": true,
"farm": {
"coins": 130
}
}
POST /game/prestige - Refactor (prestige)
Reset the farm at level 10+ for a permanent +25% coin bonus and earn Stars to spend on Legacy upgrades. Refactoring costs a coin fee that scales with prestige and current wealth (the farm state's refactor_cost); the fee funds the community treasury and a fraction of the remaining coins (10% base, up to 35% with the Golden Parachute Legacy upgrade) carries over. From prestige 50 onward, every 10 more prestige also earns a permanent Mastery point.
Minimal role: Member
Sample response
{
"ok": true,
"farm": {
"prestige": 1,
"coins": 6550
}
}
POST /game/grant - Claim the community grant
Claim the weekly community grant, paid from the treasury filled by refactor fees and divided between everyone currently eligible (capped at 2500 coins, suppressed below 250). Eligible farms are active (5+ harvests this week), below 10000 coins, and at most prestige 5.
Minimal role: Member
Sample response
{
"ok": true,
"farm": {
"coins": 2550
}
}
POST /game/legacy - Buy a Legacy upgrade
Spend Stars on a permanent Legacy upgrade that survives every refactor: autoharvest (CI Bot), multiplier (+10% coins/level), speed (+5% build speed/level), plots (+1 starting plot/level), defense (+30s grace, -5% steal loss/level), or carryover (Golden Parachute, +5% refactor carry-over/level).
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
key | form | string | yes | Legacy upgrade key. |
Sample response
{
"ok": true,
"farm": {
"stars": 1
}
}
POST /game/mastery - Buy a Mastery upgrade
Spend Mastery points (earned at prestige 50 and every 5 prestige after) on a permanent Mastery upgrade: autoreplant (Continuous Delivery, 3 points), analytics (Farm Analytics, 2 points), or contracts (Legacy Contracts, 4 points).
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
key | form | string | yes | Mastery upgrade key. |
Sample response
{
"ok": true,
"farm": {
"mastery_points": 0
}
}
POST /game/infrastructure/buy - Buy Infrastructure
Buy a permanent, expensive, prestige-gated Infrastructure building: registry (Rust/Compiler/Kernel build 15% faster; 3M coins, prestige 3), canary (12% chance to double a harvest, 6% to only refund its planting cost; 6M, prestige 8), or observability (caps what any raider can take from you at 20% of a build's value; 15M, prestige 15).
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
key | form | string | yes | Infrastructure key. |
Sample response
{
"ok": true,
"farm": {
"coins": 0
}
}
POST /game/defense/upgrade - Upgrade Defense
Buy the next Defense tier (Firewall through Zero Trust Mesh; the farm state's defensenextcost is the exact price). Each tier multiplicatively reduces what a raider takes from you and adds steal grace, but adds an ongoing daily coin upkeep of max(tier minimum, 0.2% of your balance). If you cannot pay, the tier decays by one level and only what you can afford is taken - your balance is never emptied.
Minimal role: Member
Sample response
{
"ok": true,
"farm": {
"defense_level": 1
}
}
POST /game/defense/downgrade - Downgrade Defense
Drop your Defense down one tier to escape its daily upkeep. There is no refund. Available whenever defensedowngradeavailable is true in the farm state.
Minimal role: Member
Sample response
{
"ok": true,
"farm": {
"defense_level": 0
}
}
POST /game/cosmetics/buy - Buy a cosmetic
Buy a purely cosmetic title or plot skin with coins. No gameplay effect. The farm state's cosmetics list carries each key, cost, and an owned flag.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
key | form | string | yes | Cosmetic key. |
Sample response
{
"ok": true,
"farm": {
"coins": 0
}
}
POST /game/cosmetics/equip - Equip a title
Equip an owned title cosmetic so its display name shows next to your name on the leaderboard.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
key | form | string | yes | An owned title cosmetic key. |
Sample response
{
"ok": true,
"farm": {
"active_title": "title_architect"
}
}
Playing through the API
Every action is a normal DevPlace endpoint that negotiates HTML or JSON. Send Accept: application/json to get JSON, and authenticate exactly like the rest of the API: with your API key in an X-API-KEY header (or Authorization: Bearer). Your key is on your profile page.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /game | Your farm page (HTML, or the same JSON as /game/state when asked). |
GET | /game/state | Your full farm state (always JSON). |
GET | /game/leaderboard | Top farms (public). Accepts ?board=. |
GET | /game/farm/{username} | Another member's farm. |
POST | /game/plant | Plant crop in slot. |
POST | /game/harvest | Harvest the build in slot. |
POST | /game/fertilize | Halve the remaining time of slot. |
POST | /game/buy-plot | Unlock one more plot. |
POST | /game/upgrade | Raise the CI tier. |
POST | /game/perk | Upgrade perk (yield, growth, discount, xp). |
POST | /game/daily | Claim the daily bonus. |
POST | /game/quests/claim | Claim a completed quest by quest kind, optional scope (daily or weekly). |
POST | /game/prestige | Refactor at level 10 or above; costs the current refactor_cost in coins. |
POST | /game/grant | Claim the weekly community grant from the treasury. |
POST | /game/legacy | Buy a Legacy upgrade (key) with Stars. |
POST | /game/mastery | Buy a Mastery upgrade (key) with Mastery points. |
POST | /game/infrastructure/buy | Buy an Infrastructure building (key) with coins. |
POST | /game/defense/upgrade | Buy the next Defense tier with coins. |
POST | /game/defense/downgrade | Drop one Defense tier to escape its upkeep (no refund). |
POST | /game/cosmetics/buy | Buy a cosmetic (key) with coins. |
POST | /game/cosmetics/equip | Equip an owned title cosmetic (key). |
POST | /game/farm/{username}/water | Water a neighbour's build in slot. |
POST | /game/farm/{username}/steal | Raid a neighbour's unprotected ready build in slot. |
POST bodies are form encoded (application/x-www-form-urlencoded). Form fields are slot (an integer plot index, 0-based), crop, perk, quest, scope, and key (a Legacy/Mastery/Infrastructure/cosmetic key) where the table notes them. Every own-farm POST returns {"ok": true, "farm": {...}} - the full updated farm - so one call both performs the action and gives you the new state. The two neighbour actions return the neighbour's farm as you see it ({"farm": {...}}), and a successful steal adds "stole_coins" with your payout.
Errors
An invalid action (not enough coins, wrong plot state, a still-protected harvest, an active cooldown, an unmet requirement) returns HTTP 400 with a human-readable reason:
{"error": {"status": 400, "message": "Not enough coins to plant that."}}
An unknown farm username is 404. Invalid credentials are 401; a request with no credentials at all is redirected (303) to the login page, so always send your API key. Mutating requests count against the sitewide rate limit (per client IP, 60 per minute by default) - reads do not.
Two things that happen on state reads
Loading your own farm (GET /game, GET /game/state, or the farm returned by any action) is when lazy owner-side effects run, so a scripted client should expect them:
- With the CI Bot Legacy upgrade, every ready build is auto-harvested (and with Continuous
- With a Defense building, any daily upkeep due is charged during the read, so your
coins
Delivery, auto-replanted) during the read - the state you get back is post-collection.
can be lower than the previous response predicted (and the tier one lower, if you could not pay).
Reading the state
import json, urllib.request
request = urllib.request.Request(
"https://devplace.net/game/state",
headers={"X-API-KEY": "<your-api-key>", "Accept": "application/json"},
)
with urllib.request.urlopen(request) as response:
farm = json.loads(response.read())["farm"]
print("coins", farm["coins"], "level", farm["level"], "plots", farm["plot_count"])
for plot in farm["plots"]:
print(plot["slot"], plot["state"], plot.get("crop_name"), plot.get("remaining_seconds"))
The plot shape
GET /game/state returns {"ok": true, "farm": {...}}. The farm carries your totals plus the lists you act on. A plot looks like this:
{
"slot": 0,
"state": "growing",
"crop_key": "python",
"crop_name": "Python Script",
"crop_icon": "🐍",
"reward_coins": 36,
"reward_xp": 5,
"ready_at": "2026-06-23T12:34:56+00:00",
"remaining_seconds": 73,
"watered_count": 1,
"max_waters": 3,
"can_water": false,
"can_steal": false,
"steal_coins": 0,
"steal_cooldown_seconds": 0,
"steal_reason": "",
"is_golden": false,
"fertilize_cost": 22,
"raided_fraction": 0.0,
"raided_pct": 0
}
A plot's state is empty, growing, or ready. rewardcoins/rewardxp on a plot are the crop's base rewards; the multiplied live values are on the matching entry in crops. An entry in crops carries the live cost, rewardcoins, rewardxp, growseconds, minlevel, market_state, and a locked flag, so a client can decide what is both unlocked and affordable without hard-coding the tables above.
The farm state reference
Every field on the farm object, grouped. Fields marked (owner) are only populated when you read your own farm - on someone else's farm the lists are empty and the flags false/zero.
Identity: ownerusername, owneruid, is_owner.
Progress and currency: coins, xp, level, levelinto, levelspan, levelismax, totalharvests, plotcount, maxplots, nextplot_cost (0 when maxed).
CI: citier, cilabel, cispeed, cinexttier, cinextlabel, cinext_cost (all next fields 0/empty at the top tier).
Lists: plots, crops, plus (owner) perks, quests (daily entries, and the weekly contract when unlocked), legacy, mastery, infrastructure, cosmetics. Each purchasable entry carries key, name, icon, description, its current level/owned state, the exact next cost, and a maxed flag where applicable.
Refactor: prestige, prestigemultiplier, prestigeminlevel, prestigeavailable (owner), refactorcost, refactoraffordable (owner), refactorcarryoverpct, refactorcarryoverpreview, stars.
Grant and treasury (owner): grantavailable, grantamount, grantreason, treasurybalance.
Daily: streak, dailyavailable (owner), dailystreakreset (true when your streak lapsed, so dailyreward already reflects the reset value), daily_reward.
Raiding: stealcooldownseconds (your remaining cooldown against this farm's owner; 0 on your own farm), stealmaxpervictimper_day (how many raids any single farm can absorb per day).
Mastery and lifetime stats: masterypoints, masterypointsearnedtotal, masteryanalyticsunlocked, lifetimecoinsearned, lifetimeharvests, harvestsweek.
Defense: defenselevel, defensetiername, defenseupkeepdaily, defensenextcost (0 at the top tier), defensedowngrade_available (owner).
Cosmetics and boosts: activetitle, underdogboostsecondsremaining, contractboostseconds_remaining.
Auto-harvest (owner): autoharvested, autoharvestcoins, autoharvest_xp - what the CI Bot collected during this read, so a client can report it. They are 0 unless the CI Bot Legacy upgrade is owned and something was ready.
Era: eraactive, eraname, eracoins, eraharvests.
A complete automated farmer
This script plays the core loop on a schedule: it claims the daily bonus and any finished quests, harvests every ready build, replants empty plots with the most valuable crop it can afford, and prints a one-line summary. It uses only the Python standard library. Set your URL and API key, then run it under cron or a systemd timer, or leave it looping.
#!/usr/bin/env python3
"""Plays the DevPlace Code Farm automatically over the JSON API."""
import json
import time
import urllib.error
import urllib.parse
import urllib.request
BASE = "https://devplace.net"
API_KEY = "63995001-2291-45bf-9fe3-45dae21cfcee"
POLL_SECONDS = 60
def call(method, path, fields=None):
headers = {"X-API-KEY": API_KEY, "Accept": "application/json"}
data = None
if fields is not None:
data = urllib.parse.urlencode(fields).encode()
headers["Content-Type"] = "application/x-www-form-urlencoded"
request = urllib.request.Request(BASE + path, data=data, headers=headers, method=method)
with urllib.request.urlopen(request) as response:
return json.loads(response.read())
def state():
return call("GET", "/game/state")["farm"]
def best_affordable_crop(farm):
options = [c for c in farm["crops"] if not c["locked"] and c["cost"] <= farm["coins"]]
if not options:
return None
return max(options, key=lambda c: c["reward_coins"])
def claim_free_rewards(farm):
if farm.get("daily_available"):
call("POST", "/game/daily")
if farm.get("grant_available"):
call("POST", "/game/grant")
for quest in farm.get("quests", []):
if quest.get("can_claim"):
call("POST", "/game/quests/claim", {"quest": quest["kind"], "scope": quest["scope"]})
def harvest_and_replant(farm):
for plot in farm["plots"]:
if plot["state"] == "ready":
call("POST", "/game/harvest", {"slot": plot["slot"]})
farm = state()
for plot in farm["plots"]:
if plot["state"] != "empty":
continue
crop = best_affordable_crop(farm)
if not crop:
break
call("POST", "/game/plant", {"slot": plot["slot"], "crop": crop["key"]})
farm = state()
return farm
def run():
print("Code Farm automation started.")
while True:
try:
farm = state()
claim_free_rewards(farm)
farm = harvest_and_replant(state())
print(f"coins={farm['coins']} level={farm['level']} harvests={farm['total_harvests']}")
except urllib.error.HTTPError as error:
print("api error:", error.code, error.read().decode()[:200])
except OSError as error:
print("network error, retrying:", error)
time.sleep(POLL_SECONDS)
if __name__ == "__main__":
run()
From here the natural extensions are easy: spend surplus coins with POST /game/buy-plot and POST /game/upgrade when you can afford them, raise perks with POST /game/perk, water neighbours by walking GET /game/farm/{username} and posting to its /water path for plots where canwater is true, raid where cansteal is true, and refactor with POST /game/prestige once refactor_affordable is set. Be polite to the rate limiter: mutating calls are limited per client, so a poll interval of a minute or more with one action per finished build stays well within limits.