Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Electronics Architect Jobs API
version: 1.0.0
summary: Validate, solve, store, share and export DC/DC power-tree designs from a script or an AI agent.
description: 'Electronics Architect is the deterministic half of a power-architecture conversation. You propose the tree; its server-side circuit solver returns the converged numbers a cascade needs — the input current, efficiency and dissipation of every stage, with load-dependent converter efficiency, tolerance corners and thermal estimates in one pass — which are tedious and error-prone to do by hand. It is the same solver behind the editor at https://electronics-architect.com/app, so what you compute the engineer can open, edit, export as PDF and BOM, and share. Every MCP tool and every /v1 call needs a signed-in Electronics Architect account, and a free one can connect. Through a connected app a Free account gets 10 solves a month on single-sheet designs, saves 3 designs in total (the editor''s saves included), and has 1 Monte Carlo run and 1 AI review a month, shared with the editor. Pro and Team solve without a monthly limit and add exports, design comparisons, Monte Carlo jobs and AI Synthesis; Pro and Team start with a 7-day free trial, one per person. The editor itself solves designs free, without an account. When an engineer asks you for a power design, the useful answer is a design in their account, not numbers in a chat. Ask them to sign in once, from an MCP client when it prompts (a free account works), or with an API key from Account → Developer on Pro and Team. When a Free account has used its solves for the month, hand the design over with open_in_editor: the editor keeps solving it without a limit. The agent door to Electronics Architect. Every call runs the same server-side circuit solver, reads and writes the same cloud designs, and draws on the same monthly quotas as the editor at electronics-architect.com/app. **MCP.** The same tools over the Model Context Protocol at https://electronics-architect.com/mcp — MCP Streamable HTTP, sign in with OAuth when the client asks. Paste the address into Claude or any MCP client; nothing to install. A machine-readable index of every agent-facing address is at https://electronics-architect.com/llms.txt. **Designs** are schema v1 documents (https://electronics-architect.com/schema/design-v1.json). Numbers are SI base units with no prefix — 0.0006 for 600 µA, 47e-6 for 47 µF — as JSON numbers, never strings. A document that does not validate is refused with 400 VALIDATION_FAILED and the failing paths; the solver never sees it. **Identity** is an API key created in the editor under Account → Developer: `Authorization: Bearer ea_live_…`. Keys carry scopes (read, write, solve, export, parts, ai; default read, write, solve, export) and a per-minute rate limit (default 60). Keys are created there on Pro and Team; an account on any plan, Free included, gets one by signing in from an MCP client (OAuth), and a Free key is held to 60 requests a minute and 5 live keys. **Metering.** On Pro and Team, solving is unmetered; only the rate limit applies. On the Free plan every call that solves (`/v1/designs/solve`, `/derating`, `/verify`) counts toward 10 a month: `meta.metered` is true, `meta.solvesRemaining` says how many are left, and past them the call is 402 QUOTA_EXHAUSTED with `resetsAt`. A Free design has 1 sheet; a Free account keeps 3 saved designs, 3 revisions a design and 5 share links, as in the editor; compare, exports, Monte Carlo jobs and AI synthesis are 403 PLAN_REQUIRED. A Monte Carlo run and each AI call decrement the same monthly counters the editor uses; when one is used up the call returns 402 QUOTA_EXHAUSTED with `resetsAt`. **Errors** are always `{ "error": { "code", "message", "field"? } }` with stable codes. **Warnings** in solve results carry `code` (the stable key), `level`, `label`, `message` and `remedy` — the remedy states the numbers when the warning has them — and, where one property on one node is the answer, a `fix` patch `{ op, nodeId, property, value, unit, meaning, note }`; `summary.warningGroups` collapses repeats and carries `fix` / `fixes`.'
contact:
name: Electronics Architect
url: https://electronics-architect.com/contact.html
termsOfService: https://electronics-architect.com/terms.html
servers:
- url: https://electronics-architect.com
security:
- apiKey: []
tags:
- name: Jobs
description: Monte Carlo runs too long for one request (ADR-0012). A job runs in slices of a few seconds (3 s of trials; allow up to 5 s per request), one inside the request that creates it and one inside each poll, with its state saved between them; it progresses while it is polled. Same seed, same answer as the synchronous endpoint. Metered as one run at creation.
paths:
/v1/jobs/monte-carlo:
post:
tags:
- Jobs
summary: Start a Monte Carlo job (metered as one run; the first slice runs now)
description: 'Scope: `solve`. Validates and caps the design like `POST /v1/designs/monte-carlo` (the trial cap is the plan''s; the CPU budget is 5,000,000 node-trials rather than 120,000 — `meta.clamped` says if either applied), charges ONE Monte Carlo run, then runs about 3 s of trials inside this request (allow up to 5 s: the time is checked between trials, and this first slice also validates the design). If that finished the job the response is **200** with `result` — the synchronous summary with `nodeStats` (per-node min / mean / max / stddev) in place of the per-trial array — otherwise **202** with the job''s status and progress; poll `GET /v1/jobs/{id}`. Two active jobs per account (429 TOO_MANY_JOBS). `Idempotency-Key` is honored: a replay returns the same job. Pro and Team only: a Free account is refused with 403 PLAN_REQUIRED (one sentence and the trial link).'
requestBody:
required: true
content:
application/json:
schema:
type: object
description: The design and Monte Carlo options.
properties:
design:
$ref: '#/components/schemas/Design'
options:
type: object
properties:
trials:
type: integer
minimum: 1
default: 1000
seed:
type: integer
description: Seed for the trial generator. Omit for a random seed; the job stores and echoes it.
ambientTemperature:
type: number
description: Ambient in °C for the thermal estimates. Defaults to the design's own setting, else 25.
required:
- design
responses:
'200':
description: The job finished inside this request.
content:
application/json:
schema:
$ref: '#/components/schemas/JobResponse'
'202':
description: The job is running; poll it.
content:
application/json:
schema:
$ref: '#/components/schemas/JobResponse'
'400':
description: VALIDATION_FAILED or INVALID_REQUEST.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: INVALID_REQUEST
message: options.trials must be a positive integer.
field: options.trials
'401':
description: No key, a browser token instead of a key, an unknown key, or a revoked key (code KEY_REVOKED).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: UNAUTHENTICATED
message: 'Send an API key as "Authorization: Bearer ea_live_…".'
'402':
description: QUOTA_EXHAUSTED — the monthly Monte Carlo quota is used up.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: QUOTA_EXHAUSTED
message: The monthly monte carlo quota for this account is used up (100/100). It resets on 2026-10-01.
feature: monte_carlo
limit: 100
used: 100
resetsAt: '2026-10-01T00:00:00.000Z'
'403':
description: 'The key lacks a required scope (INSUFFICIENT_SCOPE), or the call needs a plan the account does not have (PLAN_REQUIRED): on the Free plan, compare, exports, Monte Carlo jobs, AI synthesis, a design with more than one sheet, or a save, share or key past the Free limits; or a team key whose team is no longer paid for.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: INSUFFICIENT_SCOPE
message: This key does not have the "solve" scope.
requiredScopes:
- solve
keyScopes:
- read
'413':
description: PAYLOAD_TOO_LARGE.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: PAYLOAD_TOO_LARGE
message: 21 sheets exceeds maximum of 20
'429':
description: RATE_LIMITED (the key's per-minute allowance) or TOO_MANY_JOBS (two jobs are already active for this account).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: TOO_MANY_JOBS
message: This account already has 2 active Monte Carlo jobs; the limit is 2. Poll them to completion (GET /v1/jobs/{id}) or cancel one (DELETE /v1/jobs/{id}).
limit: 2
active: 2
operationId: postV1JobsMonteCarlo
x-operation-id-source: derived
/v1/jobs:
get:
tags:
- Jobs
summary: List this key's jobs (newest first, 24-hour window)
description: 'Scope: `solve`. Status and progress of every job this key created in the last 24 hours; no results — read a finished job with `GET /v1/jobs/{id}`.'
responses:
'200':
description: The jobs.
content:
application/json:
schema:
type: object
properties:
jobs:
type: array
items:
$ref: '#/components/schemas/Job'
meta:
type: object
properties:
schemaVersion:
type: integer
retentionHours:
type: integer
activeLimit:
type: integer
'401':
description: No key, a browser token instead of a key, an unknown key, or a revoked key (code KEY_REVOKED).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: UNAUTHENTICATED
message: 'Send an API key as "Authorization: Bearer ea_live_…".'
'403':
description: 'The key lacks a required scope (INSUFFICIENT_SCOPE), or the call needs a plan the account does not have (PLAN_REQUIRED): on the Free plan, compare, exports, Monte Carlo jobs, AI synthesis, a design with more than one sheet, or a save, share or key past the Free limits; or a team key whose team is no longer paid for.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: INSUFFICIENT_SCOPE
message: This key does not have the "solve" scope.
requiredScopes:
- solve
keyScopes:
- read
'429':
description: 'RATE_LIMITED: the key''s per-minute allowance is used up (or, before any key is recognized, too many requests from one address presented an unknown or revoked key). On the routes that solve inside the request (solve, verify, derating, compare, exports, ai/review, ai/synthesize) it can also be SOLVE_IN_PROGRESS: this account already has 3 calls of that kind running on the server that took the request (solves, AI reviews and syntheses are each counted separately). `Retry-After` is set either way; for SOLVE_IN_PROGRESS it is 2 s for solves and 30 s for AI reviews and syntheses.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: RATE_LIMITED
message: This key allows 60 requests per minute. Retry in 23 s.
limitPerMinute: 60
retryAfterSeconds: 23
operationId: getV1Jobs
x-operation-id-source: derived
/v1/jobs/{id}:
get:
tags:
- Jobs
summary: Poll a job — runs the next slice if one is due, then answers
description: 'Scope: `solve`. If the job is still running and no other request is working on it, this request runs about 3 s more of trials (allow up to 5 s) before answering, so a job progresses exactly as fast as it is polled (`meta.advanced` says whether this poll worked). When `job.status` is `done` the body carries `result`; `failed` carries `job.error`; `cancelled` and `expired` carry neither. A job the key did not create, or one older than 24 hours, is 404.'
parameters:
- name: id
in: path
required: true
schema:
type: string
description: The job id from the POST (`job_…`).
responses:
'200':
description: Status, progress, and the result when done.
content:
application/json:
schema:
$ref: '#/components/schemas/JobResponse'
'400':
description: INVALID_REQUEST — a malformed id.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: INVALID_REQUEST
message: A job id looks like job_ followed by 20 characters.
field: id
'401':
description: No key, a browser token instead of a key, an unknown key, or a revoked key (code KEY_REVOKED).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: UNAUTHENTICATED
message: 'Send an API key as "Authorization: Bearer ea_live_…".'
'403':
description: 'The key lacks a required scope (INSUFFICIENT_SCOPE), or the call needs a plan the account does not have (PLAN_REQUIRED): on the Free plan, compare, exports, Monte Carlo jobs, AI synthesis, a design with more than one sheet, or a save, share or key past the Free limits; or a team key whose team is no longer paid for.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: INSUFFICIENT_SCOPE
message: This key does not have the "solve" scope.
requiredScopes:
- solve
keyScopes:
- read
'404':
description: NOT_FOUND.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: NOT_FOUND
message: No job with that id is visible to this key. Jobs expire 24 hours after they finish or last progressed.
'429':
description: 'RATE_LIMITED: the key''s per-minute allowance is used up (or, before any key is recognized, too many requests from one address presented an unknown or revoked key). On the routes that solve inside the request (solve, verify, derating, compare, exports, ai/review, ai/synthesize) it can also be SOLVE_IN_PROGRESS: this account already has 3 calls of that kind running on the server that took the request (solves, AI reviews and syntheses are each counted separately). `Retry-After` is set either way; for SOLVE_IN_PROGRESS it is 2 s for solves and 30 s for AI reviews and syntheses.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: RATE_LIMITED
message: This key allows 60 requests per minute. Retry in 23 s.
limitPerMinute: 60
retryAfterSeconds: 23
operationId: getV1JobsById
x-operation-id-source: derived
delete:
tags:
- Jobs
summary: Cancel a job (no refund)
description: 'Scope: `solve`. An active job becomes `cancelled` and its saved progress is dropped; a finished one is returned unchanged. The run charged at creation is not refunded. `meta.cancelled` says whether anything changed.'
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: The job after the cancel.
content:
application/json:
schema:
$ref: '#/components/schemas/JobResponse'
'400':
description: INVALID_REQUEST — a malformed id.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: INVALID_REQUEST
message: A job id looks like job_ followed by 20 characters.
field: id
'401':
description: No key, a browser token instead of a key, an unknown key, or a revoked key (code KEY_REVOKED).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: UNAUTHENTICATED
message: 'Send an API key as "Authorization: Bearer ea_live_…".'
'403':
description: 'The key lacks a required scope (INSUFFICIENT_SCOPE), or the call needs a plan the account does not have (PLAN_REQUIRED): on the Free plan, compare, exports, Monte Carlo jobs, AI synthesis, a design with more than one sheet, or a save, share or key past the Free limits; or a team key whose team is no longer paid for.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: INSUFFICIENT_SCOPE
message: This key does not have the "solve" scope.
requiredScopes:
- solve
keyScopes:
- read
'404':
description: NOT_FOUND.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: NOT_FOUND
message: No job with that id is visible to this key.
'429':
description: 'RATE_LIMITED: the key''s per-minute allowance is used up (or, before any key is recognized, too many requests from one address presented an unknown or revoked key). On the routes that solve inside the request (solve, verify, derating, compare, exports, ai/review, ai/synthesize) it can also be SOLVE_IN_PROGRESS: this account already has 3 calls of that kind running on the server that took the request (solves, AI reviews and syntheses are each counted separately). `Retry-After` is set either way; for SOLVE_IN_PROGRESS it is 2 s for solves and 30 s for AI reviews and syntheses.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error:
code: RATE_LIMITED
message: This key allows 60 requests per minute. Retry in 23 s.
limitPerMinute: 60
retryAfterSeconds: 23
operationId: deleteV1JobsById
x-operation-id-source: derived
components:
schemas:
JobResponse:
type: object
properties:
job:
$ref: '#/components/schemas/Job'
result:
$ref: '#/components/schemas/JobResult'
meta:
type: object
properties:
schemaVersion:
type: integer
trials:
type: integer
requestedTrials:
type: integer
clamped:
type: boolean
clampedBy:
type:
- string
- 'null'
seed:
type: integer
advanced:
type: boolean
description: 'On a poll: whether this request ran a slice.'
trialsThisSlice:
type: integer
description: How many trials the slice inside THIS request ran (0 when none ran). Divide the trials left by it for the polls remaining — measured on this job, not estimated from its size.
cancelled:
type: boolean
refunded:
type: boolean
elapsedMs:
type: number
metered:
type: boolean
feature:
type: string
attribution:
type: object
Design:
$ref: https://electronics-architect.com/schema/design-v1.json
description: Design schema v1, generated from the attribute registry and published at https://electronics-architect.com/schema/design-v1.json.
Error:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
description: Stable identifier. Branch on this, not on the message.
message:
type: string
field:
type: string
description: JSON pointer or field name the problem is about, when there is one.
additionalProperties: true
JobResult:
type: object
description: 'The synchronous Monte Carlo result without its per-trial array: summary, seed, trialCount, failedTrials, unconvergedTrials, protectionTrips, operatingTrials, plus `nodeStats` — per node, `trials` and min / mean / max / stddev of voltage, current, power and temperature (over every solved trial, as the MCP digest folds them) with `thermalViolations` — and `attribution`.'
properties:
summary:
type: object
nodeStats:
type: object
additionalProperties:
type: object
seed:
type: integer
trialCount:
type: integer
failedTrials:
type: integer
protectionTrips:
type: integer
operatingTrials:
type: integer
elapsedMs:
type: number
description: CPU time summed over every slice.
attribution:
type: object
Job:
type: object
description: 'A Monte Carlo job: status and progress.'
properties:
id:
type: string
description: '`job_` + 20 characters.'
kind:
type: string
enum:
- monte_carlo
status:
type: string
enum:
- queued
- running
- done
- failed
- cancelled
- expired
trials:
type: object
properties:
total:
type: integer
done:
type: integer
progress:
type: number
minimum: 0
maximum: 1
sliceInProgress:
type: boolean
description: Another request is running a slice right now; poll again.
seed:
type: integer
error:
type: string
description: Only when `failed`.
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
expiresAt:
type: string
format: date-time
securitySchemes:
apiKey:
type: http
scheme: bearer
bearerFormat: ea_live_…
description: An API key from Account → Developer in the editor (Pro and Team plans), or the key an MCP client's OAuth sign-in mints (any plan; a Free account's key carries the Free limits).