Skip to content

Skill: pick the engine

For: an AI agent deciding which MagicON AI engine answers the question in front of it.

There are four design engines. Choosing the wrong one is the most common and most expensive mistake, because every one of them returns a confident, well-formed result — so a wrong choice does not fail, it succeeds at answering a question nobody asked.

Every path and rate limit below was verified against the production API on 2026-09-09. Base URL https://api.pcbgenerator.com, every route POST, anonymous, Content-Type: application/json, no Authorization header.


Decide in one table

Your user's question Engine Endpoint Limit
"Design a transmitter / power amplifier chain to N dBm" design_rf_chain /api/rf-chain/design-sync 5/min
"Design a receiver / how sensitive can I get at this frequency" design_rf_receiver /api/receiver/design 30/min
"Design a radar / transceiver / T/R front end that shares one antenna" design_tr_module /api/tr-module/design 15/min
"What is the gain / NF / OIP3 of these stages" run_link_budget /api/link-budget/compute 120/min

If two of these look right, the tie-breaker is at the bottom of this page.


The four engines

design_rf_chain — a transmit chain

POST /api/rf-chain/design-sync — 5 requests/minute. The tightest limit on the platform; it does the most work.

Picks and cascades VCO → driver → attenuator pads → power amplifier → filtering → isolator → connector → substrate, converges on your output target, and returns a power flow, a power tree, a priced BOM and a power verdict.

curl -X POST https://api.pcbgenerator.com/api/rf-chain/design-sync \
  -H "Content-Type: application/json" \
  -d '{"params": {"frequency": 2.4, "targetOutputPower": 30, "application": "wifi"}}'

Note the nesting: the design point goes inside params. Frequency is in GHz here.

This route enforces no required field, and that is a trap. Measured: {} returns 200, "status": "success", a selected PA (CG2H40010F) and a 1.0 dBm output. It answered a design point you did not state, so a 200 from this route is not evidence that you asked a meaningful question.

The response tells you, if you look: chain.params echoes the design point it actually used, and on that empty call it reads {"frequency": null, "target_output_power": 0, "application": null, …}. Compare chain.params against what you sent before you report anything. On a real call it echoes your values back — {"frequency": 2.4, "target_output_power": 30, "application": "wifi", …}.

Two siblings:

Variant Endpoint Limit Use when
Streaming /api/rf-chain/design 5/min You want progress events. Returns Server-Sent Events, not a JSON body
Compare alternatives /api/rf-chain/design-multi 30/min Your user asked for options or trade-offs rather than one answer

design_rf_receiver — a superheterodyne receiver

POST /api/receiver/design — 30 requests/minute.

Picks limiter → LNA → image filter → mixer → local oscillator → IF filter → IF amp → digital step attenuator, plus connector and substrate, then computes the frequency plan, cascade NF, sensitivity, ADC interface and interference products.

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

Frequency is in hertz here. Required field: rfFrequencyHz — omit it and you get 422 {"detail": "rfFrequencyHz is required to choose parts for a receiver"}.

design_tr_module — a shared-antenna front end

POST /api/tr-module/design — 15 requests/minute.

Designs a transmit chain and a receive chain and the shared element between them (T/R switch or circulator + limiter), then computes isolation, leakage and stress budgets across the junction.

curl -X POST https://api.pcbgenerator.com/api/tr-module/design \
  -H "Content-Type: application/json" \
  -d '{"frequencyGhz": 9.4, "targetOutputPowerDbm": 40,
       "application": "radar", "transmitDutyCyclePercent": 10}'

Frequency is in gigahertz here. Required: frequencyGhz and targetOutputPowerDbm.

Reach for this whenever one antenna is shared, even if your user only described one direction. Designing the transmitter and the receiver as two separate calls gives you two chains with nothing joining them — no isolation budget, no leakage budget, no stress check on the part that carries full transmit power, and no shared-path insertion loss. Those budgets are the reason this engine exists. See Design a module.

POST /api/link-budget/compute — 120 requests/minute. The cheapest call here, by an order of magnitude, and the right one for what-ifs.

Takes an ordered list of stages you supply and returns cascaded gain, Friis noise figure, reciprocal-sum OIP3 and P1dB headroom. It selects nothing.

curl -X POST https://api.pcbgenerator.com/api/link-budget/compute \
  -H "Content-Type: application/json" \
  -d '{"stages": [{"name": "LNA", "gainDB": 15, "nfDB": 1.2},
                  {"name": "IF filter", "gainDB": -1.5, "nfDB": 1.5}],
       "inputPowerDbm": -80}'

Measured: totalGainDB 13.5, cascadedNfDB 1.2428, finalOutputDbm −66.5.

Required: stages — omit it and you get 422 {"detail": "missing_stages"}.

The stage keys are gainDB and nfDB — capital DB. Spell them gainDb / nfDb and the same request still returns 200, with totalGainDB: 0.0 and cascadedNfDB: null, because the stages parsed as stages with no figures in them. Measured, both spellings, on the same two stages. A zero cascade from a chain that obviously has gain is the signature; check your key casing before you report it.

Use it when your user brought their own parts, when they want to know what one change does, or when you would otherwise burn a 5/min design call to answer "what if the LNA had 2 dB more gain".

⚠ Every number in a link budget is a number you supplied. Nothing in it is grounded in the catalogue, so the result is exactly as good as its inputs. If the stage figures did not come from your user or from a design result you already have, do not present the answer as a computed fact about real hardware.


The compute / design split

The receiver and the T/R module each exist twice: a compute-only route that does maths on stages you supply, and a design route that picks catalogue parts first and then computes. This is the most common wrong turn agents take.

Engine Compute only Limit Picks parts and computes Limit
Receiver /api/receiver 60/min /api/receiver/design 30/min
T/R module /api/tr-module 60/min /api/tr-module/design 15/min
Cascade /api/link-budget/compute 120/min (none — it never selects)
Transmit chain (none — it always selects) /api/rf-chain/design-sync 5/min

Rule: if your user described an intent ("X-band, 10 MHz bandwidth, 12 dB SNR"), you have no stages to give, so you want the /design route. If they described hardware ("here are my four stages"), you want the compute-only route.

⚠ The compute-only routes are cheaper and faster, which makes them tempting. They are the wrong tool for an intent, and they will not tell you so: POST /api/receiver refuses without stages (422), but POST /api/tr-module answers {} with a 200 — an empty question with a confident-looking shape around it.


Units and names differ per route. Read the field name.

Route Frequency field Unit
/api/rf-chain/design-sync params.frequency GHz
/api/receiver/design rfFrequencyHz Hz
/api/tr-module/design frequencyGhz GHz

9400000000 and 9.4 are the same frequency. A route that wanted GHz and got 9400000000 will not correct you.


Tie-breakers

  • "Design a radar."design_tr_module. A radar shares one antenna, and the isolation, leakage and stress budgets are the point.
  • "Design a transmitter" but they mentioned receiving too.design_tr_module. Two independent chains are not a module.
  • "How good is this receiver?" with parts named.run_link_budget if you have the stage figures; /api/receiver if you have full cascade stages and want the frequency plan and ADC interface too.
  • "What are my options?"/api/rf-chain/design-multi (30/min) rather than five separate 5/min design calls.
  • You are iterating on one variable.run_link_budget at 120/min, then one design call to confirm.
  • You are unsure between two engines. → Ask your user one question. It costs less than a design call and far less than a confident answer to the wrong question.

Limits, errors and state

  • Limits are per calling IP, and exceeding one returns 429. Anything without its own limit falls back to 1000 requests/hour.
  • 422 means your request is missing or has a malformed field. The detail names the field — for example "frequencyGhz is required to design a T/R module". Ask your user for it. Do not invent it.
  • 500 is our fault. Retry once, then report it. A malformed design point is a 422, never a 500.
  • Nothing persists. No session, no project id, no result to fetch later, and nothing to poll. If a second call needs a figure from the first, carry it yourself.