A House Divided A House DividedDocumentation
Changelog
API/Public API

A House Divided - Public API v1

Last updated 2026-08-24

Base URL: https://ahousedividedgame.com

Use the API to build tools that read game data or automate fund transfers and forex trades. Generate keys in Settings -> API Keys in-game.

This document is canonical. The old in-app /api-guide page redirects here.

Authentication#

All API requests require a personal API key in the X-API-Key header:

X-API-Key: ahd_pub_...   # public scope (read-only)
X-API-Key: ahd_priv_...  # private scope (read + write)

Key scopes:

Prefix Scope Access
ahd_pub_ Public Read-only access to all public endpoints. Cannot send funds or trade forex.
ahd_priv_ Private All public endpoints + send campaign funds + trade forex. Treat like a password.

You can have up to 3 active keys per scope type. The full token is shown only once at creation.

Rate limits#

Category Limit
Public read 60 req/min per key
Fund transfers 20 req/min per key
Forex trades 30 req/min per key
Key management 10 req/min

Rate-limited responses return HTTP 429 with a Retry-After header (seconds).

Usage guidelines#

Response envelope#

Success:

{ "ok": true, ... }

Error:

{ "error": "Human-readable message", "code": "ERROR_CODE" }

Stability contract#

/v1/ endpoints are additive-only. Fields may be added; existing fields will not be removed or renamed. Breaking changes will be released under /v2/.

All timestamps are UTC ISO 8601.

Error responses#

Status Code Meaning
401 missing / invalid No API key, or key not found/revoked
403 insufficient scope Public key used on a private endpoint
403 Transfers are paused Admin has temporarily paused fund transfers
403 Currency exchange is not yet enabled Forex is disabled on this server
429 rate_limited Too many requests, check Retry-After

Public read endpoints#

All accessible with any personal API key via X-API-Key.

GET /api/public/v1/game#

Current game state and turn timing.

Field Type Description
ok boolean Always true on success
found boolean Whether game data was found
currentTurn number Current turn number
gameDate string In-game date (YYYY-MM-DD)
nextTurnAt string | null ISO 8601 timestamp of next turn
turnDurationMs number Turn duration in milliseconds

GET /api/public/v1/character#

Search characters. Requires name or discordId query param. Alias: GET /api/public/v1/characterSearch (same params and response).

Param Type Description
name string Character name (partial match)
discordId string Discord user ID

Response: ok, found, characters[] with fields:

Field Type Description
id string Character ObjectId
name string Display name
bio string | null Character biography
countryId string | null Home country code
party string Party name
partyId string | null Party ObjectId
partyColor string Hex color
state string Home state name
stateCode string Home state code
position string Current office/position
politicalInfluence number PI score
nationalInfluence number NPI score
favorability number Favorability rating
campaignFunds number Campaign treasury
netWorth number Total net worth
isCeo boolean Whether CEO of a corporation
profileUrl string Relative profile URL
activeElection object | null Current election info if running

GET /api/public/v1/character/[id]#

Full character details by public sequential id (e.g. 75) or ObjectId. Same field shape as the characters array above, wrapped as { ok, found, character } with additional detail fields.

GET /api/public/v1/character/[id]/career#

Character career history.

Field Type Description
ok boolean Always true
found boolean Whether the character exists
characterId string Character ObjectId
characterName string Display name
career[].type string Entry type (election, appointment, etc.)
career[].office string | null Office held
career[].party string | null Party at time
career[].fromState string | null Start turn/term
career[].toState string | null End turn/term

GET /api/public/v1/character/[id]/achievements#

Achievements earned by a character.

Field Type Description
achievements[].id string Achievement ID
achievements[].name string | null Display name
achievements[].description string | null Description text
achievements[].icon string | null Emoji/icon
achievements[].category string | null Category
achievements[].isHidden boolean Whether hidden from others
achievements[].earnedAt string | null ISO 8601 timestamp

GET /api/public/v1/party?id=ID&country=CODE#

Party details. Both id and country params required.

Field Type Description
party.id string Party ObjectId
party.name string Party name
party.abbreviation string | null Short name
party.color string Hex color
party.economicPosition number Economic axis position
party.socialPosition number Social axis position
party.memberCount number Active member count
party.seatCount number Legislative seats held
party.treasury number Party treasury balance
party.chairName string | null Party chair name
party.topMembers array Top 5 members by influence

GET /api/public/v1/country#

List all countries. Returns countries[] of { id, name, governmentType }.

GET /api/public/v1/country/[code]#

Country details by code (e.g. US, GB).

Field Type Description
countryId string Country code
name string Country name
governmentType string Regime type (e.g. presidential, parliamentary)
population number | null Population count
currentLeader object | null { name, party, profileUrl } or null
legislatureComposition[].partyName string Party name
legislatureComposition[].seats number Seats held
legislatureComposition[].seatPct number Percentage of total
lastElectionCycle number | null Last election cycle number

GET /api/public/v1/country/[code]/legislature#

Legislature details for a country.

Field Type Description
chamber string Chamber name
totalSeats number Total legislative seats
composition array Party seat breakdown
pendingBills[].id string Bill ObjectId
pendingBills[].title string Bill title
pendingBills[].status string Bill status
recentlyPassed array Recently passed bills ({ yes, no } vote tally per entry)

GET /api/public/v1/country/[code]/economy#

Economic indicators for a country.

Field Type Description
primeRate number | null Current central bank rate
inflation number | null Current inflation rate
gdpGrowth number | null GDP growth rate
chair object | null Central bank chair { name, profileUrl }
rateHistory array [{ turn, rate }] historical rates
stockMarket.totalMarketCap number Total market cap
stockMarket.change24h number 24h change percentage

GET /api/public/v1/government?country=CODE#

Government overview. Requires country query param.

Field Type Description
officials[].role string Position title
officials[].characterName string | null Office holder name
officials[].party string | null Party affiliation
officials[].section string "executive" or "leadership"
cabinet array Cabinet members
governmentFormation object Varies by regime type

GET /api/public/v1/elections?country=CODE[&state=STATE]#

Active elections. Requires country; optional state.

Field Type Description
elections[].id string Election ObjectId
elections[].electionType string Type (primary, general, etc.)
elections[].state string State code
elections[].status string Status (open, closed, etc.)
elections[].candidates[].characterName string Candidate name
elections[].candidates[].party string Party name
elections[].candidates[].isNPP boolean Non-party member

GET /api/public/v1/elections/[id]#

Detailed election info including candidates, votes, and phases.

Field Type Description
election.electionType string Type
election.status string Current status
election.totalSeats number Seats contested
phase object { inPrimary, inGeneral, isUpcoming, isEnded }
incumbent object | null { name, party } or null
candidates array Full candidate list with details
votes object | null Vote tallies and snapshots

GET /api/public/v1/news?limit=N[&category=CAT]#

News feed. Optional limit and category.

Field Type Description
posts[].id string Post ObjectId
posts[].title string | null Headline
posts[].content string | null Body text
posts[].authorName string | null Author
posts[].isSystem boolean System-generated post
posts[].category string | null Category tag
posts[].countryId string | null Related country
posts[].createdAt string | null ISO 8601 timestamp

GET /api/public/v1/legislation?country=CODE[&status=pending|passed|failed][&limit=N]#

Bills and votes. Optional filters.

Field Type Description
bills[].id string Bill ObjectId
bills[].title string Bill title
bills[].sponsor string | null Sponsor name
bills[].status string pending, passed, or failed
bills[].vote object { yes, no, abstain }
bills[].effects array [{ metric, direction }]

GET /api/public/v1/market?type=SECTOR&country=CODE&page=N#

Stock market data. type param required. Pass view=share for shares, view=unowned for unowned sectors.

Field Type Description
mode string "share" or "unowned"
sectorType string Requested sector type
page / totalPages number Pagination
companies | sectors array Results (depends on mode)

GET /api/public/v1/bonds?corp=NAME&page=N#

Bond market data. Optional corp and page.

Field Type Description
bonds[].id string Bond ObjectId
bonds[].couponRate number Coupon rate (e.g. 0.05 = 5%)
bonds[].maturityLabel string | null Maturity description
bonds[].totalIssued number Total bonds issued
bonds[].marketPrice number Current market price
bonds[].yieldToMaturity number | null YTM
bonds[].defaulted boolean Whether bond is in default
pagination object { page, perPage, totalCount, totalPages }

GET /api/public/v1/corporations#

List all corporations. Returns corporations[] of { id, name, sequentialId, type, countryId }.

GET /api/public/v1/corporation?name=X[&id=N]#

Corporation details. Requires name or id. Note: id is the corporation's sequentialId (e.g. 112), not the Mongo ObjectId.

Field Type Description
id string Corporation ObjectId
name string Corporation name
type / typeLabel string Corporation type (+ human-readable label)
ceo object | null { name, profileUrl }
financials object Revenue, income, costs, dividends
balanceSheet object { cashOnHand, marketCapitalization, totalDebt }
shareStructure object Shares, price, float, shareholders
creditRating object Rating, score, components
bonds array Corporate bonds
sectors array Operational sectors

GET /api/public/v1/leaderboard?country=CODE[&metric=METRIC][&limit=N]#

Player rankings. Metrics: npi, pi, favorability, funds, actions.

Field Type Description
metric string Requested metric
characters[].rank number Position
characters[].name string Character name
characters[].party string Party name
characters[].funds number Campaign funds
characters[].politicalInfluence number PI score
characters[].profileUrl string Profile link

GET /api/public/v1/country/[code]/history?limit=N[&type=TYPE][&beforeTurn=N]#

Append-only country event log (leader changes, bill enactments, referendums, regime changes, international relations). Written by the turn processor.

Param Type Description
limit number 1-200, default 50
type string Filter by eventType (e.g. leader_change, bill_enacted, referendum_passed)
beforeTurn number Pagination cursor: events strictly before this turn

Response rows: events[].turn, eventType, title, officeType, characterId / characterName / party, billScope, details, iterationStartingYear, timestamp.

GET /api/public/v1/country/[code]/battles?limit=N#

Recent battle reports involving the country (as declarer or target), newest turn first.

Response rows: battles[].theaterId, declarerCountry, targetCountry, attackers, defenders, turn, result (null = no contact), noContact, unopposedAdvance, controlBefore / controlAfter (front-line movement, null when unknown).

GET /api/public/v1/conflicts?country=CODE[&status=STATUS][&limit=N]#

Conflicts, newest first. Filter by involved country (host or belligerent) and/or status (active, escalating, winding_down, resolved).

Response rows: conflicts[].conflictId (public sequential number), name, hostCountry, region, type, status, bloc, terrain, severity, intensity, control (share of host held by side B, 0-100), supplyA / supplyB, and both sides as { label, countries, kind, backer }.

GET /api/public/v1/parties?country=CODE#

All parties for a country, ordered by member count. Seat counts come from the elected-officials roster so they reconcile with the legislature endpoints.

Response rows: parties[].id (sequential id usable with /party?id=), name, abbreviation, color, economicPosition, socialPosition, memberCount, seatCount, treasury, isDefault.

GET /api/public/v1/elections/archives?country=CODE[&limit=N][&type=TYPE]#

Completed/resolved elections for a country, newest first.

Response rows: elections[].id, seatId, electionType, state, cycle, electionYear, totalSeats, startTime / endTime, status, totalVotes, finalized, candidateCount, and winner: { characterName, party, votes } when a final tally exists.

GET /api/public/v1/funds[?slug=SLUG][&country=CODE][&scope=country|global]#

Index funds. Without slug: list all funds sorted by NAV. With slug: full detail including top holdings enriched with corporation names.

List rows: funds[].slug, name, tickerSymbol, scope, kind, countryId, sectorType, status, pauseReason, quotedNav, unitSupply, anchorCurrencyCode, backingRatio, sponsorName, expenseRatioAnnual, updatedAt.

Detail adds: reserveUnits, cashAnchor, lastRebalancedAt, charteredAtTurn, seedCapitalAnchor, windDownStartedAtTurn, topHoldings[] of { corporationId, corporationName, shares, lastValueAnchor, avgCostPerShareAnchor }.

GET /api/public/v1/corporation/shares/history?name=X[&id=N][&page=N][&pageSize=N]#

Public share-trade tape for one corporation (same data the in-game corp page shows). Requires name or id (sequential id).

Response: corporation: { id, name }, page, pageSize, total, pageCount, and entries[] of { kind, turn, createdAt, shares, pricePerShareAnchor, totalAnchor, corpCurrencyCode, from: { name }, to: { name }, note }. from/to are null when the public float is that side.

GET /api/public/v1/characters/bulk?ids=1,7,42#

Bulk character lookup for dashboards: up to 100 comma-separated sequential ids in one request. Unknown and invalid ids are skipped (match on what came back).

Response: ok, found, requested / returned counts, and characters[] with the same shape as the search endpoint.

GET /api/public/v1/meta#

Machine-readable catalog of every v1 endpoint with its params, plus base URL, auth header, rate limits, and the stability contract. Bots can validate their integration against this instead of scraping docs.

Private endpoints (send funds and forex)#

Require a private personal API key. All in-game restrictions apply identically to API requests.

POST /api/v1/transfer#

Send campaign funds to another character.

Request body:

{ "targetCharacterId": "<recipient ObjectId>", "amount": 5000 }

amount is in your character's home currency (same unit as your in-game balance, min 1000, integer).

Response: success, amount, currency (sender home currency code), senderRemainingFunds, targetName.

Restrictions:

POST /api/v1/forex/exchange#

Execute a forex market order.

Request body:

{ "fromCurrency": "USD", "toCurrency": "GBP", "amount": 1000 }

Response: success, trade.fromCurrency, trade.toCurrency, trade.fromAmount, trade.toAmount, trade.effectiveRate, trade.spreadCharged (0.275% spread; 50% destroyed, 50% to central bank).

Restrictions:

Quick start#

# Read public data (any key)
curl -H "X-API-Key: $AHD_API_KEY" \
  https://ahousedividedgame.com/api/public/v1/game

# Send funds (private key)
curl -X POST -H "X-API-Key: $AHD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"targetCharacterId":"507f1f77bcf86cd799439011","amount":5000}' \
  https://ahousedividedgame.com/api/v1/transfer

Python:

import os, requests

BASE = "https://ahousedividedgame.com"
headers = {"X-API-Key": os.environ["AHD_API_KEY"]}

game = requests.get(f"{BASE}/api/public/v1/game", headers=headers).json()
print(f"Turn {game['currentTurn']}")
Ask