Skip to content

API reference for LLMs

This page is written for an AI agent calling MagicON AI directly. It is not the human manual — for that, start at the documentation home.

The endpoints, rate limits and worked-example figures below were verified against the live production API on 2026-09-08.


In one paragraph

MagicON AI exposes a set of RF and PCB design engines over plain HTTPS. They are deterministic solvers over a catalog of 2,400+ real RF components: you send a design point, you get a complete result back in one response. No account, no API key, no OAuth, no job queue. The engines are the same ones behind the web app — there is no separate "API version" of the maths.


Connecting

Base URL

https://api.pcbgenerator.com

Authentication: none for every engine listed on this page. Send no Authorization header. (CAD export routes — KiCad, ODB++, Gerber — do require a signed-in user and are not covered here.)

Headers: Content-Type: application/json. That is the whole list.

Transport: HTTPS only. There is no MCP server yet. If you are an MCP-capable client, you call these as ordinary HTTP requests.

Schemas: the full machine-readable request and response schema for every route is at /openapi.json. This page gives you orientation and guarantees; the OpenAPI document gives you field-level detail, and it is generated from the running code so it cannot drift.


The engines

Every path below is POST, anonymous, and was confirmed reachable in production. The rate limit is per calling IP address.

Engine Endpoint Limit First required field
Transmit chain design /api/rf-chain/design-sync 5/min (none enforced — see trap 3)
Transmit chain design (streaming) /api/rf-chain/design 5/min params, streamed over SSE
Compare chain alternatives /api/rf-chain/design-multi 30/min params
Receiver — compute only /api/receiver 60/min stages
Receiver — pick parts and compute /api/receiver/design 30/min rfFrequencyHz
T/R module — compute only /api/tr-module 60/min (see note below)
T/R module — assemble and compute /api/tr-module/design 15/min frequencyGhz
Link budget cascade /api/link-budget/compute 120/min stages
Stackup solver /api/solver/solve 30/min layer_count
Thermal analysis /api/stackups/thermal-analysis/preview 10/min analysis_input
PDN impedance /api/pdn/analyze 30/min plane_pairs
Regulatory compliance /api/compliance/check 1000/hour layers

Anything without its own limit falls back to the global default of 1000 requests per hour. Exceeding a limit returns HTTP 429.

Choosing between the two receiver routes — this is the mistake agents make most often. POST /api/receiver is the pure-maths path: you supply every cascade stage and it computes. POST /api/receiver/design is the intent path: you supply a frequency and it picks real catalog parts and then computes. If you only know "X-band, 10 MHz bandwidth", you want the second one. The same split exists for T/R modules.


A complete worked example

A real design point, and the figures production actually returned for it.

Request

curl -X POST https://api.pcbgenerator.com/api/receiver/design \
  -H "Content-Type: application/json" \
  -d '{"rfFrequencyHz": 9400000000, "bandwidthHz": 10000000, "requiredSnrDb": 12}'

Response — 200, sub-second, about 36 KB. These are the headline figures:

Field Value
cascade.totalGainDB 31.65
cascade.cascadedNfDB 1.7798
cascade.sensitivityDbm −90.22
cascade.noiseFloorDbm −104.0
cascade.cascadedOip3Dbm 27.24
cascade.sfdrDb 65.21
needsPartFlags [] — every slot filled

And the parts it chose, one per slot:

Slot Part
limiter TGL2209-SM
lna BFP840ESD
imageFilter B095MB1S
mixer CMD183C4
localOscillator ADF5611
ifFilter CBP2-1090C+
ifAmp PHA-23LN+
digitalStepAttenuator HMC1119
connector SMA-J-P-H-ST-EM1
substrate RO3003-50ohm-MS

Top-level response keys: cascade, parts, stages, frequencyPlan, adcInterface, interference, analysis, bom, alternatives, needsPartFlags, assumptions, warnings.


What we stand behind, and what we don't

This is the part that matters most, and it is the reason this page exists separately from the manual.

Numbers in the response are computed. They come from published component data and from solvers, not from a language model. Nothing on the response side is generated text dressed up as a figure.

Numbers in your request are yours. The engines have no way to tell whether a value you sent was stated by your user or invented by you. They will compute faithfully from whatever you send. If you pass a noise figure your user never gave you, you will get a precise, authoritative-looking, wrong answer — and it will be wrong because of your input, not our maths. Pass through what your user actually said.

Read assumptions before reporting a result. When the engine has to choose something you did not specify, it says so in plain language. The example above returned, among others:

"IF of 1128.0 MHz was CHOSEN BY THE ENGINE (~12% of RF, floored at 5x the signal bandwidth), not supplied. Pass an explicit IF to override."

If you report the result without that sentence, you are presenting our choice as your user's decision.

An empty slot is declared, never filled. If no catalog part can satisfy a position in the chain, it comes back named in needsPartFlags and the slot stays empty. We do not substitute a plausible part. An empty needsPartFlags means every slot was genuinely filled.

Check warnings too. They carry things like regulatory overages, compression, and stress-rating verdicts. The example above returned six.


Errors

Status Meaning What to do
422 Your request is missing or has a malformed field Read detail — it names the field, e.g. "rfFrequencyHz is required to choose parts for a receiver". Ask your user, do not invent the value.
429 Rate limit exceeded Back off; the limits are in the table above.
500 Our fault Retry once, then report it. A malformed design point is a 422, never a 500.

Error bodies are {"detail": "..."} — either a plain sentence from the engine, or FastAPI's structured validation list when a typed field is missing.


Things that will trip you up

  1. Frequencies are in hertz on some routes and gigahertz on others. The receiver takes rfFrequencyHz (9400000000); the T/R module takes frequencyGhz (9.4). Read the field name, not the number.
  2. POST /api/rf-chain/design streams. It returns Server-Sent Events, not a JSON body. Use /api/rf-chain/design-sync if you want one response.
  3. The {} request is not a validity test. /api/rf-chain/design-sync and /api/tr-module both answer 200 to an empty body with null-filled results. A 200 does not by itself mean you asked a meaningful question.
  4. Nothing persists. Every call is independent. There is no session, no project id, and no result to fetch later. If a second call needs a figure from the first, carry it yourself.
  5. There is nothing to poll. Every engine returns its complete result in the same response. If you find yourself looking for a job_id, you are looking for an API we do not have.