1. What the Market API is
The Market Operator must expose a machine interface
that Market Code participants (and the public, for open data) can call
without opening the Webill UI. That interface is the SAWEM
Market API under /api/v1 (plus
/internal for MO↔︎SO).
This volume documents every operation published at:
GET /api/v1/publication/openapi
That document is generated from the live Phoenix router + catalogue
(WB.Sawem.Api.Publication.openapi/1). If this manual and
the OpenAPI disagree, trust the OpenAPI and file a V20
TODO against this volume.
1.1 The problem this volume solves
V9 · Market Operations teaches what the market does and which screens a BRP, MO or SO uses. It does not catalogue HTTP contracts. Integrators need method, path, auth, bodies, status codes, and — critically — whether Webill itself calls the route from a screen or a cron job.
1.2 Two channels, one rulebook
| Channel | What it is | Who uses it |
|---|---|---|
Market API (/api/v1,
/internal) |
OpenAPI HTTP contract | External BRPs, Network Operators, MO↔︎SO links, sandbox/conformance |
| Org / MO / SO UI | LiveViews + domain (WB.Sawem.*, Ash) |
Humans in the product |
Important. As of this release, no LiveView
and no Oban worker performs HTTP calls to /api/v1.
Background BRP automation uses WB.Brp.MoGateway /
SoGateway. Screens call domain modules that enforce the
same Market Code rules. Each endpoint chapter therefore states the
caller explicitly — often no in-app HTTP caller, with a
parallel UI or job named for orientation.
1.3 Where to fetch the machine-readable source
GET /api/v1/publication/openapi HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Sibling publications (also public):
/api/v1/publication/data-exchange,
/formulation, /audit.
Follow along. With the app running, open
http://localhost:4000/api/v1/publication/openapi(or your deploy host). You should see an OpenAPI 3.1 document whosepathsmatch this volume’s endpoint index (§16).
Where this is taught. Market behaviour and screens — V9. Background crontab catalog — V21 §3.
2. Conventions and authentication
Every /api/v1 response stamps
X-Sawem-Server-Time and
X-Sawem-Market-Code-Version. Send the version header on
every request; a mismatch is a hard reject.
2.1 Security schemes
| Scheme | Used for | How it is enforced |
|---|---|---|
| PublicOpenData | Published prices, zones, accession register, publications, events | No Bearer. Still send X-Sawem-Market-Code-Version: 2.3.
Optional x-sawem-mpid on /events adds the
caller’s own private events to the public stream. |
| ParticipantMtlsOAuth | Party-scoped registry, DAM/IDM, dispatch, metering read, balancing, §15 settlement | Bearer JWT always (outside sandbox and
:sql_sandbox). Obtain it from
POST /api/v1/oauth/token with
grant_type=client_credentials; client_id is
the MPID, falling back to brp_code. The token’s
mpid claim must match the party in the path. mTLS
is opt-in per registration: where a certificate fingerprint is
pinned, the dedicated API listener also requires a matching client
certificate — the certificate binds the machine and the token binds the
party. HMAC signing is opt-in per registration: where a
signing key is active, unsafe methods must also carry
X-Sawem-Signature and X-Sawem-Timestamp. |
| InternalParty | /internal/* MO↔︎SO |
Mutual TLS on the dedicated API listener: the SHA-256 fingerprint of
the client certificate matches the configured
system_operator or market_operator identity.
X-Sawem-Internal-Party is honoured only
inside the conformance sandbox and :sql_sandbox tests. |
x-sawem-mpid alone is refused outside those two
exemptions with header_authentication_retired (401,
§16(2)(a)), pointing at the token endpoint. Curl samples later in this
volume still show the header as illustrative shorthand — a reader
copying an example to understand a field should not need three
credentials to follow it. Production callers present a bearer token.
Cross-party reads return 404, never 403 — a 403 would confirm the resource exists.
2.2 Unsafe methods, idempotency and signatures
POST, PUT, PATCH and
DELETE require an Idempotency-Key header —
including public dry-runs such as zone allocate. Replays with the same
key return the original outcome.
Where the registration has opted into HMAC signing, those writes also
require X-Sawem-Signature (HMAC-SHA256 hex over
METHOD\nPATH\nCanonical.digest(body)\nTIMESTAMP) and a
companion X-Sawem-Timestamp inside a short freshness
window. A captured signature replayed under a new
idempotency key after the window is stale. A verbatim retry under the
original key still returns the cached response. The key
is symmetric, issued and rotated through the same credential model as
the client secret — not a detached JWS.
2.3 Numbers and time
| Rule | Detail |
|---|---|
| Decimals | JSON strings (e.g. "10.500"), never
bare floats |
| Timestamps | Must carry explicit +02:00 (SAST). Bare Z
is rejected |
| Dates | ISO YYYY-MM-DD in SAST calendar sense |
2.4 Error envelope
Failures use a shared error object (see OpenAPI
ErrorEnvelope): machine code, human
message, optional field_errors[]. Treat
unknown 4xx/5xx bodies as opaque; do not scrape HTML.
2.5 Pipelines
| Pipeline | Routes | Notes |
|---|---|---|
:sawem_public_api |
Public GETs | Version + clock headers; no Idempotency-Key |
:sawem_oauth |
POST /api/v1/oauth/token |
Dedicated :oauth_token rate class; no Idempotency-Key;
no bearer |
:sawem_api |
Party + most writes | Version, clock, authentication, optional mTLS/HMAC, idempotency, rate limit |
| Internal | /internal/* |
mTLS on the dedicated listener; header only in sandbox/test |
Where this is taught. Gate timing and bid desks — V9 §4. Credential lifecycle on the MO console — V11 §21.12.
3. Who calls the API
Read this chapter before treating any curl example as “what the app does”.
3.1 Caller classes
| Class | Meaning | Badge in endpoint chapters |
|---|---|---|
| External BRP / NO | Another system HTTP-calls Webill’s MO API | External party / NO |
| Public client | Website or tool, no participant token | External public |
| Internal MO↔︎SO | Operator integration | Internal |
| Sandbox | Test/conformance only | Sandbox |
| No in-app HTTP caller | Defined for the contract; Webill UI/jobs do not HTTP-hit it | Highlighted on every such op |
3.2 Parallel UI (same capability, not the same socket)
| Capability | Screen | Route |
|---|---|---|
| Public prices | Price board | /prices · Public.PriceBoardLive |
| BRP registration | Registration | /org/brp · RegistrationLive |
| Bid desk / DAM + IDM | Bid desk | /org/brp/bid-desk · BidDeskLive |
| Registry / PoDs / BGs | Market registry | /org/brp/registry ·
MarketRegistryLive |
| Standing data | Standing data | /org/brp/standing-data ·
StandingDataLive |
| Notices | Notices | /org/brp/notices · NoticesLive |
| Imbalance | Imbalance | /org/brp/imbalance · ImbalanceLive |
| Reconciliation | Reconciliation | /org/brp/reconciliation ·
ReconciliationLive |
| SO instructions feed | SO feed | /org/brp/so · SoFeedLive |
| MO console | Market desk | /mo · Mo.MarketDeskLive |
| SO console | Dispatch desk | /so · So.DispatchDeskLive |
3.3 Parallel Oban jobs (gateway, not OpenAPI HTTP)
These crontab entries automate BRP obligations via
MoGateway / SoGateway. They are
not HTTP clients of /api/v1. Full catalog:
V21
§3.
| Cron (SAST) | Worker | Market capability |
|---|---|---|
0 3 * * * |
WB.Brp.Workers.SubmitDamBids |
Day-ahead submission |
0 12 * * * |
WB.Brp.Workers.FetchSchedule |
Day-ahead schedule fetch |
30 6 * * * |
WB.Brp.Workers.ComputeImbalance |
Balancing / imbalance |
0 4,10,16,22 * * * |
WB.Brp.Workers.IdmMonitor |
IDM re-declarations |
*/15 * * * * |
WB.Brp.Workers.PollSo |
Dispatch instructions |
5 0 * * * |
WB.Brp.Workers.ArchiveSoInstructions |
Instruction archive |
30 12 * * * |
WB.Brp.Workers.RefreshPriceForecast |
Price context (not OpenAPI) |
0 7 3 * * |
WB.Brp.Workers.ReconcileMonth |
Monthly market reconciliation |
3.4 Sandbox flag
/api/v1/sandbox/* exists in the catalogue always, but
routes mount only when
Application.compile_env(:wb_wheeling, :sawem_sandbox) is
true (test today). Production must not expose clock
freeze.
Careful. If an endpoint chapter says no in-app HTTP caller, do not invent a screen that “posts to the API”. Point integrators at the OpenAPI and operators at the parallel UI/job instead.
4. Network zones
Public open data for the Network Zone model the MO mirrors from the SO (V12 §2).
Live source: filter tags containing Network
zones in GET /api/v1/publication/openapi.
4.1 List Network Zones in the published model
GET /api/v1/registry/network-zones
Returns every Network Zone in the model the Market Operator currently mirrors from the System Operator (§3.3(4)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
as_of |
string | optional | Effective date for the read (SAST). Defaults to today. |
model_version |
string | optional | Pin a specific zone-model edition
(e.g. PROV-2026-07). |
Responses
- 200 — Zone list plus coverage integrity summary.
- 404
Example — what you are doing
You are reading
list network zones in the published model for the
identifiers in the path.
GET /api/v1/registry/network-zones HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External / public clients — no in-app HTTP caller. Zone teaching and the MO zones panel use domain (
Mo.ZonesPanel/ siteZoneAllocation). CSV sibling for gaps:GET /mo/zones/gaps.csv(not OpenAPI). See V12 §2.
4.2 Show one Network Zone by code
GET /api/v1/registry/network-zones/:code
Returns a single Network Zone from the published model (§3.3(4)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
code |
string | required | Network Zone code (e.g. Z1) as published in the zone
model. |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
as_of |
string | optional | Effective date for the read (SAST). |
model_version |
string | optional | Pin a specific zone-model edition. |
Responses
- 200
NetworkZone— The Network Zone row. - 404
Example — what you are doing
You are reading show one network zone by code for the
identifiers in the path.
GET /api/v1/registry/network-zones/GP-JHB HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External / public clients — no in-app HTTP caller. Zone teaching and the MO zones panel use domain (
Mo.ZonesPanel/ siteZoneAllocation). CSV sibling for gaps:GET /mo/zones/gaps.csv(not OpenAPI). See V12 §2.
4.3 Dry-run Network Zone allocation for a coordinate
POST /api/v1/registry/network-zones/allocate
Takes a WGS84 coordinate and returns which Network Zone (if any) would receive a Point of Delivery there (§3.3(4)(a)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Required on this unsafe method |
| Request body | ZoneAllocateRequest |
Responses
- 200
NetworkZone— Allocated zone facts, or an unallocated outcome with gap context. - 404
Example — what you are doing
You are dry-running whether a WGS84 coordinate would land in a Network Zone before you register a Point of Delivery — nothing is written.
POST /api/v1/registry/network-zones/allocate HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
"lat": "-25.7479",
"lon": "28.2293",
"as_of": "2026-07-09"
}
Who calls this. External / public clients — no in-app HTTP caller. Zone teaching and the MO zones panel use domain (
Mo.ZonesPanel/ siteZoneAllocation). CSV sibling for gaps:GET /mo/zones/gaps.csv(not OpenAPI). See V12 §2.
4.4 List locations the zone model does not cover
GET /api/v1/registry/network-zones/gaps
Returns the published gap catalogue — coordinates and regions the Network Zone model does not yet allocate (§3.3).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
as_of |
string | optional | Effective date for the gaps snapshot (SAST). |
model_version |
string | optional | Pin a specific zone-model edition. |
Responses
- 200 — Gap catalogue for the selected model edition.
- 404
Example — what you are doing
You are reading
list locations the zone model does not cover for the
identifiers in the path.
GET /api/v1/registry/network-zones/gaps HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External / public clients — no in-app HTTP caller. Zone teaching and the MO zones panel use domain (
Mo.ZonesPanel/ siteZoneAllocation). CSV sibling for gaps:GET /mo/zones/gaps.csv(not OpenAPI). See V12 §2.
4.5 Show the constrained scheduling model
GET /api/v1/network-model ·
GET /api/v1/network-model/{version}
The other half of §3.3(4). §4.1–§4.4 give you the zones; this gives you what the System Operator schedules between them — inter-zonal load-carrying capability per corridor, and the interconnectors to SAPP with the capacity on each.
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
as_of |
string | optional | Effective date for the read (SAST). Defaults to today. |
Responses
- 200 — Zones with their export/import roll-up, corridors, interconnectors, provenance, publication status and a capability table.
- 404 — the named version is not registered. An unregistered version is not an empty 200: that would read as “this version exists and has no zones”.
Careful — read
provenancebefore you use a number. The zone model is provisional and the corridor capability is assumed: §3.3(4)(b) makes capability the System Operator’s figure to publish and it has not.publication.publishable_to_participantsisfalsewhile any figure is assumed, and every corridor, interconnector and zonal roll-up carries its ownbasis.provenance.capabilitystates the derivation method, its known limitations, and what supersedes it. Do not use an assumed figure as a planning, connection or trading input.
Why you would call it. §3.3(5) gives you two months’
notice of a model revision expressly so you can adjust Trading Unit
definitions before a boundary change invalidates a registration
(§2.1(212)(a) forbids a unit spanning zones). Pin as_of to
evaluate the edition that is coming, not only the one in force.
GET /api/v1/network-model HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
4.6 List active zone constraint flags
GET /api/v1/network-model/zone-constraints?active=true
§3.3(6) lets the System Operator indicate at any time that imports to, or exports from, a Network Zone are constrained. §13.10(2) reads the direction to decide which Trading Units drop out of a Balancing Group for the constraint’s duration: where exports are flagged, units contributing additional balancing energy are excluded; where imports are flagged, units contributing reduced energy are.
Responses
- 200 — the flags in force, and a
notewhen there are none.
Note. Flags are issued at runtime and are not part of the §3.3(4) model, so an empty
flagsarray carries the reason: it means no zone is currently flagged, not that the network is unconstrained.
Who calls this. External / public clients, and the BRP’s own System Operator screen, which renders the model per zone — see V12 §2.
5. Party registry
Accession register (public) and your party-scoped Trading Units, Balancing Groups and Points of Delivery (V9 §3).
Live source: filter tags containing Party
registry in GET /api/v1/publication/openapi.
Request samples below still show x-sawem-mpid as
shorthand. Production authentication is §2.
5.1 Public accession register
GET /api/v1/registry/accession-register
Returns the Market Operator’s published accession register (§6.2(9)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Responses
- 200 — Published accession rows.
- 404
Example — what you are doing
You are reading public accession register for the
identifiers in the path.
GET /api/v1/registry/accession-register HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External / public clients — no in-app HTTP caller. Accession pedagogy: V9 §3.
5.2 Show your party record
GET /api/v1/registry/participants/:mpid
Returns your §6 party record — state, clocks, settlement accounts and identifiers (§6.3.1).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
mpid |
string | required | Market Participant ID assigned by the MO, or your
brp_code (accepted for continuity with MS2 callers).
Cross-party val |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
as_of |
string | optional | Effective date for the read (SAST). |
Responses
- 200 — Your party payload.
- 404
Example — what you are doing
You are reading show your party record for the
identifiers in the path.
GET /api/v1/registry/participants/BRP001 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
5.3 List your Balancing Groups
GET /api/v1/registry/participants/:mpid/balancing-groups
Returns Balancing Groups you have designated under §13.10(1).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
mpid |
string | required | Market Participant ID assigned by the MO, or your
brp_code (accepted for continuity with MS2 callers).
Cross-party val |
Responses
- 200 — Your Balancing Groups and member Trading Units.
- 404
Example — what you are doing
You are reading list your balancing groups for the
identifiers in the path.
GET /api/v1/registry/participants/BRP001/balancing-groups HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
5.4 Create a Balancing Group
POST /api/v1/registry/participants/:mpid/balancing-groups
Designates Trading Units into a Balancing Group (§13.10(1)).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
mpid |
string | required | Market Participant ID assigned by the MO, or your
brp_code (accepted for continuity with MS2 callers).
Cross-party val |
Responses
- 201 — Created Balancing Group.
- 404
Example — what you are doing
You are calling POST to create a Balancing Group.
POST /api/v1/registry/participants/BRP001/balancing-groups HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Trading Units —
TradingUnitsLive/org/trading-units(designate / amend / cancel); Market registry —MarketRegistryLive/org/brp/registry(read-only). Taught in V9 §3.6.
5.4A Amend a Balancing Group
PATCH /api/v1/registry/balancing-groups/:id
Writes a new effective-dated row with
supersedes_id. The current row is not mutated. Re-triggers
the §7.1(5) cutoff.
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
Responses
- 200 — The successor Balancing Group.
- 422 — Cutoff or membership refused.
5.4B Cancel a Balancing Group
DELETE /api/v1/registry/balancing-groups/:id
Cancels the group from the cutoff floor. reason is
mandatory (?reason=).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
Responses
- 200 — The cancelled Balancing Group
(
status: CANCELLED). - 422 — Reason missing.
5.5 List your default notices and suspension orders
GET /api/v1/registry/participants/:mpid/notices
Returns Default Notices and suspension orders that apply to your party, with remedy dates (§6.4, §15.10(7)).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
mpid |
string | required | Market Participant ID assigned by the MO, or your
brp_code (accepted for continuity with MS2 callers).
Cross-party val |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
as_of |
string | optional | Effective date for notice evaluation (SAST). |
Responses
- 200 — Notices, suspensions and pay-now-argue-later reminder.
- 404
Example — what you are doing
You are reading
list your default notices and suspension orders for the
identifiers in the path.
GET /api/v1/registry/participants/BRP001/notices HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Notices —
NoticesLive/org/brp/notices. Taught in V9 §3.
5.6 List your Trading Units
GET /api/v1/registry/participants/:mpid/trading-units
Returns Trading Units registered under the given participant (§7.1, §7.2).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
mpid |
string | required | Market Participant ID assigned by the MO, or your
brp_code (accepted for continuity with MS2 callers).
Cross-party val |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
as_of |
string | optional | Effective date for the list (SAST). |
Responses
- 200 — Array of Trading Units.
- 404
Example — what you are doing
You are reading list your trading units for the
identifiers in the path.
GET /api/v1/registry/participants/BRP001/trading-units HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
5.7 Register a Trading Unit
POST /api/v1/registry/participants/:mpid/trading-units
Registers a new Trading Unit under your party (§7.1(1), §7.2).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | TradingUnitCreate |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
mpid |
string | required | Market Participant ID assigned by the MO, or your
brp_code (accepted for continuity with MS2 callers).
Cross-party val |
Responses
- 201
TradingUnit— Registered Trading Unit. - 404
Example — what you are doing
You are calling POST to register a Trading Unit.
POST /api/v1/registry/participants/BRP001/trading-units HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
"official_name": "Midrand DC Unit 1",
"unit_class": "LOAD",
"network_zone_code": "GP-JHB",
"effective_from": "2026-08-01"
}
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
5.8 Delete (end-date) a Point of Delivery
DELETE /api/v1/registry/points-of-delivery/:pod_id
Ends a Point of Delivery you own (§7.2).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
pod_id |
string | required | Point of Delivery identifier. Own-party only; a foreign PoD is 404, never 403. |
Responses
- 200 — PoD ended or removed.
- 404
Example — what you are doing
You are calling DELETE to delete (end-date) a Point of
Delivery.
DELETE /api/v1/registry/points-of-delivery/POD-DEMO-1 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
5.9 Show one Trading Unit
GET /api/v1/registry/trading-units/:tuid
Returns a single Trading Unit you own (§7.2), including capacity, certified reserve and zone allocation outcome.
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
as_of |
string | optional | Effective date for the read (SAST). |
Responses
- 200
TradingUnit— The Trading Unit. - 404
Example — what you are doing
You are reading show one trading unit for the
identifiers in the path.
GET /api/v1/registry/trading-units/TU-DEMO-1 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
5.10 Request a §7.1(5) Trading Unit modification
POST /api/v1/registry/trading-units/:tuid/modifications
Submits a modification against a Trading Unit you own (§7.1(5)).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 201 — Accepted modification (pending or applied per rules).
- 202 — Modification accepted for later effectiveness.
- 404
Example — what you are doing
You are calling POST to request a §7.1(5) Trading Unit
modification.
POST /api/v1/registry/trading-units/TU-DEMO-1/modifications HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
5.11 List Points of Delivery on a Trading Unit
GET /api/v1/registry/trading-units/:tuid/points-of-delivery
Lists Points of Delivery registered on your Trading Unit (§7.2(1)(i)).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Points of Delivery on the unit.
- 404
Example — what you are doing
You are reading
list points of delivery on a trading unit for the
identifiers in the path.
GET /api/v1/registry/trading-units/TU-DEMO-1/points-of-delivery HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
5.12 Register a Point of Delivery
POST /api/v1/registry/trading-units/:tuid/points-of-delivery
Registers a Point of Delivery on your Trading Unit (§7.2(1)(i)).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | PointOfDeliveryCreate |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 201 — Registered Point of Delivery.
- 404
Example — what you are doing
You are calling POST to register a Point of
Delivery.
POST /api/v1/registry/trading-units/TU-DEMO-1/points-of-delivery HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `PointOfDeliveryCreate` in OpenAPI components */
}
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
6. Standing data
Operational parameters the MO needs before a unit can bid — profiles, certifications, standing blocks.
Live source: filter tags containing Standing
data in GET /api/v1/publication/openapi.
Request samples below still show x-sawem-mpid as
shorthand. Production authentication is §2.
6.1 Show energy-constrained profile (§7.3)
GET /api/v1/registry/trading-units/:tuid/energy-constrained-profile
Returns the energy-constrained standing-data profile for your unit (§7.3).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Energy-constrained profile.
- 404
Example — what you are doing
You are reading show energy-constrained profile (§7.3)
for the identifiers in the path.
GET /api/v1/registry/trading-units/TU-DEMO-1/energy-constrained-profile HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Standing data —
StandingDataLive/org/brp/standing-data. Taught in V9 §3.
6.2 Replace energy-constrained profile (§7.3)
PUT /api/v1/registry/trading-units/:tuid/energy-constrained-profile
Full-replace PUT of the §7.3 energy-constrained profile.
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Stored energy-constrained profile.
- 404
Example — what you are doing
You are calling PUT to replace energy-constrained
profile (§7.3).
PUT /api/v1/registry/trading-units/TU-DEMO-1/energy-constrained-profile HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Standing data —
StandingDataLive/org/brp/standing-data. Taught in V9 §3.
6.3 List reserve certifications for a Trading Unit
GET /api/v1/registry/trading-units/:tuid/reserve-certifications
Lists SO reserve-certification requests and outcomes for your unit (§7.2(q)–(s)).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Certification history / current requests.
- 404
Example — what you are doing
You are reading
list reserve certifications for a trading unit for the
identifiers in the path.
GET /api/v1/registry/trading-units/TU-DEMO-1/reserve-certifications HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Standing data —
StandingDataLive/org/brp/standing-data. Taught in V9 §3.
6.4 Request a reserve certification
POST /api/v1/registry/trading-units/:tuid/reserve-certifications
Opens a reserve-certification request for a category on your Trading Unit (§7.2(q)–(s)).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 201 — Certification request accepted.
- 202 — Certification request queued for SO action.
- 404
Example — what you are doing
You are calling POST to request a reserve
certification.
POST /api/v1/registry/trading-units/TU-DEMO-1/reserve-certifications HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Standing data —
StandingDataLive/org/brp/standing-data. Taught in V9 §3.
6.5 Show standing data for a Trading Unit
GET /api/v1/registry/trading-units/:tuid/standing-data
Returns the §7.2 standing-data blocks currently in force for your Trading Unit.
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
as_of |
string | optional | Effective date for the read (SAST). |
Responses
- 200 — Standing-data blocks for the unit.
- 404
Example — what you are doing
You are reading show standing data for a trading unit
for the identifiers in the path.
GET /api/v1/registry/trading-units/TU-DEMO-1/standing-data HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Standing data —
StandingDataLive/org/brp/standing-data. Taught in V9 §3.
6.6 Patch standing data for a Trading Unit
PATCH /api/v1/registry/trading-units/:tuid/standing-data
Updates §7.2 standing data on your Trading Unit.
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Updated standing data.
- 404
Example — what you are doing
You are calling PATCH to patch standing data for a
Trading Unit.
PATCH /api/v1/registry/trading-units/TU-DEMO-1/standing-data HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Standing data —
StandingDataLive/org/brp/standing-data. Taught in V9 §3.
6.7 Show storage profile (§7.4)
GET /api/v1/registry/trading-units/:tuid/storage-profile
Returns the storage standing-data profile for your storage Trading Unit (§7.4).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Storage profile.
- 404
Example — what you are doing
You are reading show storage profile (§7.4) for the
identifiers in the path.
GET /api/v1/registry/trading-units/TU-DEMO-1/storage-profile HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Standing data —
StandingDataLive/org/brp/standing-data. Taught in V9 §3.
6.8 Replace storage profile (§7.4)
PUT /api/v1/registry/trading-units/:tuid/storage-profile
Full-replace PUT of the §7.4 storage profile for your unit.
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Stored storage profile.
- 404
Example — what you are doing
You are calling PUT to replace storage profile
(§7.4).
PUT /api/v1/registry/trading-units/TU-DEMO-1/storage-profile HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Standing data —
StandingDataLive/org/brp/standing-data. Taught in V9 §3.
7. Day-ahead market
Gate, validate/put/get submissions, own prices/settlement, and public DAM publications (V9 §4).
Live source: filter tags containing Day-ahead
market in GET /api/v1/publication/openapi.
Request samples below still show x-sawem-mpid as
shorthand. Production authentication is §2.
7.1 Contingency-reserve adequacy report
GET /api/v1/dam/adequacy-report/:trading_date
Reports contingency-reserve adequacy per Trading Period (§9.1(5)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — Per-period adequacy report.
- 404
Example — what you are doing
You are reading contingency-reserve adequacy report for
the identifiers in the path.
GET /api/v1/dam/adequacy-report/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External BRP clients — Oban/UI use MoGateway / domain, not this path. No in-app HTTP caller to
/api/v1/.... Parallel UI: Bid deskBidDeskLive/org/brp/bid-desk(gate + submission viaWB.Sawem.Submission.Gate). Background: ObanWB.Brp.Workers.SubmitDamBidsdaily 03:00 andFetchScheduledaily 12:00 go throughWB.Brp.MoGateway(Mock/adapter), not this OpenAPI route. See V9 §4.
7.2 Published day-ahead system prices
GET /api/v1/dam/prices/:trading_date
Returns the published day-ahead System Marginal Price set for the Trading Day (§2.3(m), §9.8).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200
DamPrices— Published DAM prices for the Trading Day. - 404
Example — what you are doing
You are fetching the published price board for one Trading Day so a website or external BRP tool can display SMP without a participant token.
GET /api/v1/dam/prices/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External BRP clients — Oban/UI use MoGateway / domain, not this path. No in-app HTTP caller to
/api/v1/.... Parallel UI: Bid deskBidDeskLive/org/brp/bid-desk(gate + submission viaWB.Sawem.Submission.Gate). Background: ObanWB.Brp.Workers.SubmitDamBidsdaily 03:00 andFetchScheduledaily 12:00 go throughWB.Brp.MoGateway(Mock/adapter), not this OpenAPI route. See V9 §4.
7.3 Published day-ahead schedules
GET /api/v1/dam/schedules/:trading_date
Returns the published day-ahead schedule report for the Trading Day (§2.3(m), §9.10(2)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — Published schedules with settlement blocks.
- 404
Example — what you are doing
You are reading published day-ahead schedules for the
identifiers in the path.
GET /api/v1/dam/schedules/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External BRP clients — Oban/UI use MoGateway / domain, not this path. No in-app HTTP caller to
/api/v1/.... Parallel UI: Bid deskBidDeskLive/org/brp/bid-desk(gate + submission viaWB.Sawem.Submission.Gate). Background: ObanWB.Brp.Workers.SubmitDamBidsdaily 03:00 andFetchScheduledaily 12:00 go throughWB.Brp.MoGateway(Mock/adapter), not this OpenAPI route. See V9 §4.
7.4 Day-ahead gate state for a Trading Day
GET /api/v1/registry/dam/gate/:trading_date
Returns whether the day-ahead gate is open, closed or extended for the Trading Day (§9.3, API-SPEC §4.3).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — Gate state, closes-at and server time.
- 404
Example — what you are doing
You are reading day-ahead gate state for a trading day
for the identifiers in the path.
GET /api/v1/registry/dam/gate/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — Oban/UI use MoGateway / domain, not this path. No in-app HTTP caller to
/api/v1/.... Parallel UI: Bid deskBidDeskLive/org/brp/bid-desk(gate + submission viaWB.Sawem.Submission.Gate). Background: ObanWB.Brp.Workers.SubmitDamBidsdaily 03:00 andFetchScheduledaily 12:00 go throughWB.Brp.MoGateway(Mock/adapter), not this OpenAPI route. See V9 §4.
7.5 Own day-ahead settlement lines for a Trading Day
GET /api/v1/registry/dam/settlement/:trading_date
Returns §9.8–§9.9 day-ahead settlement lines for Trading Units you own.
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | optional | Optional Trading Unit filter; omit for all units you own. |
Responses
- 200 — Settlement lines for the day.
- 404
Example — what you are doing
You are reading
own day-ahead settlement lines for a trading day for the
identifiers in the path.
GET /api/v1/registry/dam/settlement/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — Oban/UI use MoGateway / domain, not this path. No in-app HTTP caller to
/api/v1/.... Parallel UI: Bid deskBidDeskLive/org/brp/bid-desk(gate + submission viaWB.Sawem.Submission.Gate). Background: ObanWB.Brp.Workers.SubmitDamBidsdaily 03:00 andFetchScheduledaily 12:00 go throughWB.Brp.MoGateway(Mock/adapter), not this OpenAPI route. See V9 §4.
7.6 Get your day-ahead submission
GET /api/v1/registry/dam/submissions/:trading_date/:tuid
Returns the day-ahead submission currently held for your Trading Unit and Trading Day (§9.3).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
include |
string | optional | Set to periods to expand per-period declarations in the
response. |
Responses
- 200
DamSubmission— Your stored submission. - 404
Example — what you are doing
You are reading get your day-ahead submission for the
identifiers in the path.
GET /api/v1/registry/dam/submissions/2026-07-09/:tuid HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — Oban/UI use MoGateway / domain, not this path. No in-app HTTP caller to
/api/v1/.... Parallel UI: Bid deskBidDeskLive/org/brp/bid-desk(gate + submission viaWB.Sawem.Submission.Gate). Background: ObanWB.Brp.Workers.SubmitDamBidsdaily 03:00 andFetchScheduledaily 12:00 go throughWB.Brp.MoGateway(Mock/adapter), not this OpenAPI route. See V9 §4.
7.7 Put (full-replace) a day-ahead submission
PUT /api/v1/registry/dam/submissions/:trading_date/:tuid
Full-replace day-ahead submission for one Trading Unit and Trading Day (§9.3).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | DamSubmission |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200
DamSubmission— Stored submission acknowledgement / echo. - 404
Example — what you are doing
You are full-replacing your day-ahead bid/offer for one Trading Unit
on one Trading Day. The gate must still be open;
submission_seq must advance.
PUT /api/v1/registry/dam/submissions/2026-07-09/:tuid HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
"trading_date": "2026-07-10",
"tuid": "TU-EXAMPLE",
"submission_seq": 1,
"periods": [
{
"period": 1,
"curves": [{ "mw": "10.0", "price_r_mwh": "850.00" }]
}
],
"rescheduling_consent": "WILLING"
}
In this app, Bid Desk and SubmitDamBids use domain /
MoGateway instead of this HTTP route.
Who calls this. External BRP clients — Oban/UI use MoGateway / domain, not this path. No in-app HTTP caller to
/api/v1/.... Parallel UI: Bid deskBidDeskLive/org/brp/bid-desk(gate + submission viaWB.Sawem.Submission.Gate). Background: ObanWB.Brp.Workers.SubmitDamBidsdaily 03:00 andFetchScheduledaily 12:00 go throughWB.Brp.MoGateway(Mock/adapter), not this OpenAPI route. See V9 §4.
7.8 Validate a day-ahead submission without storing it
POST /api/v1/registry/dam/submissions/:trading_date/validate
Dry-runs §9.3 validation against your body for the Trading Day — same
rules as PUT, nothing persisted.
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | DamSubmission |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — Validation passed (or structured field errors on rejection paths).
- 404
Example — what you are doing
You are calling POST to validate a day-ahead submission
without storing it.
POST /api/v1/registry/dam/submissions/2026-07-09/validate HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
"trading_date": "2026-07-10",
"tuid": "TU-EXAMPLE",
"submission_seq": 1,
"periods": [
{
"period": 1,
"curves": [{ "mw": "10.0", "price_r_mwh": "850.00" }]
}
],
"rescheduling_consent": "WILLING"
}
Who calls this. External BRP clients — Oban/UI use MoGateway / domain, not this path. No in-app HTTP caller to
/api/v1/.... Parallel UI: Bid deskBidDeskLive/org/brp/bid-desk(gate + submission viaWB.Sawem.Submission.Gate). Background: ObanWB.Brp.Workers.SubmitDamBidsdaily 03:00 andFetchScheduledaily 12:00 go throughWB.Brp.MoGateway(Mock/adapter), not this OpenAPI route. See V9 §4.
7.9 Own-unit day-ahead prices and opportunity costs
GET /api/v1/registry/dam/unit-prices/:trading_date/:tuid
Returns per-period SMP alongside your unit’s scheduled quantities and reserve unit costs (§9.8, MO-SPEC §5.3).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Per-period own-unit price and schedule detail.
- 404
Example — what you are doing
You are fetching the published price board for one Trading Day so a website or external BRP tool can display SMP without a participant token.
GET /api/v1/registry/dam/unit-prices/2026-07-09/:tuid HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — Oban/UI use MoGateway / domain, not this path. No in-app HTTP caller to
/api/v1/.... Parallel UI: Bid deskBidDeskLive/org/brp/bid-desk(gate + submission viaWB.Sawem.Submission.Gate). Background: ObanWB.Brp.Workers.SubmitDamBidsdaily 03:00 andFetchScheduledaily 12:00 go throughWB.Brp.MoGateway(Mock/adapter), not this OpenAPI route. See V9 §4.
8. Intraday market
IDM auctions, re-declarations, consent, own schedules/settlement, public IDM prices (V9 §5).
Live source: filter tags containing Intraday
market in GET /api/v1/publication/openapi.
Request samples below still show x-sawem-mpid as
shorthand. Production authentication is §2.
8.1 Published anonymised IDM prices
GET /api/v1/idm/prices/:trading_date
Returns the published intraday price set for the Trading Day (§10(10), §2.3(m)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — Published IDM prices with anonymised stacks.
- 404
Example — what you are doing
You are fetching the published price board for one Trading Day so a website or external BRP tool can display SMP without a participant token.
GET /api/v1/idm/prices/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External BRP clients — Oban/UI use MoGateway / domain. No in-app HTTP caller. Parallel UI: Bid desk IDM tab; MO
idm_board. Background:WB.Brp.Workers.IdmMonitorevery 30 minutes via MoGateway. V9 §5.
8.2 List IDM auction iterations for a Trading Day
GET /api/v1/registry/idm/auctions/:trading_date
Returns intraday auction iterations open or completed for the Trading Day (§10).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — IDM auction iterations and states.
- 404
Example — what you are doing
You are reading
list idm auction iterations for a trading day for the
identifiers in the path.
GET /api/v1/registry/idm/auctions/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — Oban/UI use MoGateway / domain. No in-app HTTP caller. Parallel UI: Bid desk IDM tab; MO
idm_board. Background:WB.Brp.Workers.IdmMonitorevery 30 minutes via MoGateway. V9 §5.
8.3 Get your IDM re-declarations
GET /api/v1/registry/idm/redeclarations/:trading_date/:tuid
Returns re-declarations held for your Trading Unit on the Trading Day (§10).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Re-declarations for the unit/day.
- 404
Example — what you are doing
You are reading get your idm re-declarations for the
identifiers in the path.
GET /api/v1/registry/idm/redeclarations/2026-07-09/:tuid HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — Oban/UI use MoGateway / domain. No in-app HTTP caller. Parallel UI: Bid desk IDM tab; MO
idm_board. Background:WB.Brp.Workers.IdmMonitorevery 30 minutes via MoGateway. V9 §5.
8.4 Put an intraday re-declaration
PUT /api/v1/registry/idm/redeclarations/:trading_date/:tuid
Submits a §10 re-declaration for your Trading Unit against a specific auction iteration.
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | IdmRedeclaration |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200
IdmRedeclaration— Accepted re-declaration. - 404
Example — what you are doing
You are calling PUT to put an intraday
re-declaration.
PUT /api/v1/registry/idm/redeclarations/2026-07-09/:tuid HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
"iteration": 1,
"reason": "plant derate",
"periods": [{ "period": 12, "mw": "8.5" }]
}
Who calls this. External BRP clients — Oban/UI use MoGateway / domain. No in-app HTTP caller. Parallel UI: Bid desk IDM tab; MO
idm_board. Background:WB.Brp.Workers.IdmMonitorevery 30 minutes via MoGateway. V9 §5.
8.5 Put IDM rescheduling consent
PUT /api/v1/registry/idm/rescheduling-consent/:trading_date/:tuid
Declares whether your unit is WILLING or
NON_WILLING for intraday rescheduling (§10).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Stored consent.
- 404
Example — what you are doing
You are calling PUT to put IDM rescheduling consent.
PUT /api/v1/registry/idm/rescheduling-consent/2026-07-09/:tuid HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
"rescheduling_consent": "WILLING"
}
Who calls this. External BRP clients — Oban/UI use MoGateway / domain. No in-app HTTP caller. Parallel UI: Bid desk IDM tab; MO
idm_board. Background:WB.Brp.Workers.IdmMonitorevery 30 minutes via MoGateway. V9 §5.
8.6 Own IDM schedules for a Trading Day
GET /api/v1/registry/idm/schedules/:trading_date
Returns intraday schedules for Trading Units you own (§10).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | optional | Optional Trading Unit filter. |
Responses
- 200 — IDM schedules for your units.
- 404
Example — what you are doing
You are reading own idm schedules for a trading day for
the identifiers in the path.
GET /api/v1/registry/idm/schedules/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — Oban/UI use MoGateway / domain. No in-app HTTP caller. Parallel UI: Bid desk IDM tab; MO
idm_board. Background:WB.Brp.Workers.IdmMonitorevery 30 minutes via MoGateway. V9 §5.
8.7 Own IDM settlement for a Trading Day
GET /api/v1/registry/idm/settlement/:trading_date
Returns intraday settlement detail for your units (§10).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | optional | Optional Trading Unit filter. |
Responses
- 200 — IDM settlement lines.
- 404
Example — what you are doing
You are reading own idm settlement for a trading day for
the identifiers in the path.
GET /api/v1/registry/idm/settlement/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — Oban/UI use MoGateway / domain. No in-app HTTP caller. Parallel UI: Bid desk IDM tab; MO
idm_board. Background:WB.Brp.Workers.IdmMonitorevery 30 minutes via MoGateway. V9 §5.
9. Dispatch
SO instructions, acknowledgement, Instructed Energy, availability revisions (V12 §3.2).
Live source: filter tags containing
Dispatch in
GET /api/v1/publication/openapi.
Request samples below still show x-sawem-mpid as
shorthand. Production authentication is §2.
9.1 Post an availability revision
POST /api/v1/registry/availability-revisions/:trading_date/:tuid
Posts an availability revision for your Trading Unit on the Trading Day (§11 / API-SPEC §7.3).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
Responses
- 200 — Availability revision accepted.
- 201 — Availability revision created.
- 404
Example — what you are doing
You are calling POST to post an availability
revision.
POST /api/v1/registry/availability-revisions/2026-07-09/:tuid HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. External BRP clients — SO poll via gateway. No in-app HTTP caller. Parallel UI: SO feed
SoFeedLive/org/brp/so; SO consoleDispatchDeskLive/so. Background:WB.Brp.Workers.PollSoevery 15 minutes,ArchiveSoInstructionsdaily 00:05 via SoGateway. V12 §3.2.
9.2 Instructed Energy with calculation trace
GET /api/v1/registry/instructed-energy/:trading_date
Returns Instructed Energy for your unit(s) on the Trading Day, with the MW·minute trace (§13.4.1).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | optional | Trading Unit to calculate for. |
period |
string | optional | Optional Trading Period start (…+02:00). |
Responses
- 200
InstructedEnergy— Instructed Energy with method and trace. - 404
Example — what you are doing
You are reading instructed energy with calculation trace
for the identifiers in the path.
GET /api/v1/registry/instructed-energy/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — SO poll via gateway. No in-app HTTP caller. Parallel UI: SO feed
SoFeedLive/org/brp/so; SO consoleDispatchDeskLive/so. Background:WB.Brp.Workers.PollSoevery 15 minutes,ArchiveSoInstructionsdaily 00:05 via SoGateway. V12 §3.2.
9.3 Acknowledge a dispatch instruction
POST /api/v1/registry/instructions/:external_ref/acknowledge
Acknowledges a dispatch instruction by its external_ref
(§11).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
external_ref |
string | required | External reference on a dispatch instruction — the id you use when acknowledging. |
Responses
- 200 — Acknowledgement recorded.
- 404
Example — what you are doing
You are calling POST to acknowledge a dispatch
instruction.
POST /api/v1/registry/instructions/INSTR-55/acknowledge HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. External BRP clients — SO poll via gateway. No in-app HTTP caller. Parallel UI: SO feed
SoFeedLive/org/brp/so; SO consoleDispatchDeskLive/so. Background:WB.Brp.Workers.PollSoevery 15 minutes,ArchiveSoInstructionsdaily 00:05 via SoGateway. V12 §3.2.
9.4 List dispatch instructions for a Trading Day
GET /api/v1/registry/instructions/:trading_date
Returns SO dispatch instructions for Trading Units you own (§11).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | optional | Optional Trading Unit filter. |
Responses
- 200
DispatchInstructions— Own-unit instructions for the day. - 404
Example — what you are doing
You are reading
list dispatch instructions for a trading day for the
identifiers in the path.
GET /api/v1/registry/instructions/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — SO poll via gateway. No in-app HTTP caller. Parallel UI: SO feed
SoFeedLive/org/brp/so; SO consoleDispatchDeskLive/so. Background:WB.Brp.Workers.PollSoevery 15 minutes,ArchiveSoInstructionsdaily 00:05 via SoGateway. V12 §3.2.
10. Metering
Network Operator meter batches and Actual Energy reads (V9 §14).
Live source: filter tags containing
Metering in
GET /api/v1/publication/openapi.
Request samples below still show x-sawem-mpid as
shorthand. Production authentication is §2.
10.1 Allocation exceptions for a Trading Day
GET /api/v1/registry/metering/allocation-exceptions/:trading_date
Lists allocation exceptions affecting your metering picture for the Trading Day (§12).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — Allocation exceptions.
- 404
Example — what you are doing
You are reading allocation exceptions for a trading day
for the identifiers in the path.
GET /api/v1/registry/metering/allocation-exceptions/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. Parallel UI: allocation exceptions on Bid Desk / MO exception inbox (domain
ExceptionInbox). V9 §14.
10.2 Meter / Actual Energy for a Point of Delivery
GET /api/v1/registry/metering/points-of-delivery/:pod_id/:trading_date
Returns metering / allocated figures for a Point of Delivery you own on the Trading Day (§12).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
pod_id |
string | required | Point of Delivery identifier. Own-party only; a foreign PoD is 404, never 403. |
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — PoD-level metering / allocation for the day.
- 404
Example — what you are doing
You are reading
meter / actual energy for a point of delivery for the
identifiers in the path.
GET /api/v1/registry/metering/points-of-delivery/POD-DEMO-1/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
10.3 Submit a Network-Operator meter reading batch
POST /api/v1/registry/metering/readings
Submits a meter reading batch for Points of Delivery in your Network Operator jurisdiction (§12).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Required on this unsafe method |
| Request body | MeteringBatch |
Responses
- 200 — Batch accepted.
- 202 — Batch accepted for asynchronous allocation.
- 404
Example — what you are doing
You are calling POST to submit a Network-Operator meter
reading batch.
POST /api/v1/registry/metering/readings HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
"trading_date": "2026-07-09",
"readings": [
{ "pod_id": "POD-1", "period": 1, "mwh": "1.250", "quality": "ACTUAL" }
]
}
Who calls this. Network Operator external systems — no in-app HTTP caller. Intended for Network Operator meter gateways. Org meter ingest for wheeling uses the setup/live pipeline, not this SAWEM batch path. V9 §14.
10.4 Actual Energy for a Trading Unit
GET /api/v1/registry/metering/trading-units/:tuid/:trading_date
Returns allocated Actual Energy for your Trading Unit and Trading Day (§12).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200
ActualEnergy— Allocated Actual Energy with vintage. - 404
Example — what you are doing
You are reading actual energy for a trading unit for the
identifiers in the path.
GET /api/v1/registry/metering/trading-units/TU-DEMO-1/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
11. Balancing
Unit/group balancing legs and published BPB/BPS (V9 §6).
Live source: filter tags containing
Balancing in
GET /api/v1/publication/openapi.
Request samples below still show x-sawem-mpid as
shorthand. Production authentication is §2.
11.1 Published balancing prices and anonymised stacks
GET /api/v1/balancing/prices/:trading_date
Returns published balancing prices (BPB / BPS), imbalance volumes and diagnostics (§13.7, §13.8, §2.3(m)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200
BalancingPrices— Published balancing prices for the Trading Day. - 404
Example — what you are doing
You are fetching the published price board for one Trading Day so a website or external BRP tool can display SMP without a participant token.
GET /api/v1/balancing/prices/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External BRP clients — imbalance worker via gateway. No in-app HTTP caller. Parallel UI: Imbalance
ImbalanceLive/org/brp/imbalance. Background:WB.Brp.Workers.ComputeImbalancedaily 06:30 via MoGateway. V9 §6.
11.2 Balancing legs for a Balancing Group
GET /api/v1/registry/balancing/balancing-groups/:group_id/:trading_date
Returns balancing settlement rolled up for a Balancing Group you own (§13.10).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
group_id |
string | required | Balancing Group identifier belonging to the calling party. |
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — Balancing group settlement for the day.
- 404
Example — what you are doing
You are reading balancing legs for a balancing group for
the identifiers in the path.
GET /api/v1/registry/balancing/balancing-groups/BG-1/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — imbalance worker via gateway. No in-app HTTP caller. Parallel UI: Imbalance
ImbalanceLive/org/brp/imbalance. Background:WB.Brp.Workers.ComputeImbalancedaily 06:30 via MoGateway. V9 §6.
11.3 Balancing legs for a Trading Unit
GET /api/v1/registry/balancing/trading-units/:tuid/:trading_date
Returns balancing settlement legs for your Trading Unit on the Trading Day (§13).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
tuid |
string | required | Trading Unit identifier (e.g. TU-7K4M2P9Q). Must belong
to the calling party; another party’s unit is **404, never 403 |
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — Balancing legs and unpriced deviation for the unit.
- 404
Example — what you are doing
You are reading balancing legs for a trading unit for
the identifiers in the path.
GET /api/v1/registry/balancing/trading-units/TU-DEMO-1/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP/NO clients — no in-app HTTP caller. The BRP UI performs the same capability through Ash/domain, not REST. Parallel screens: Market registry —
MarketRegistryLive/org/brp/registry; registration shellRegistrationLive/org/brp. Taught in V9 §3.
12. Financial settlement
Market Code §15 statements, invoices, credit cover and queries — not PPA settlement (V9 §15).
Live source: filter tags containing Financial
settlement in GET /api/v1/publication/openapi.
Request samples below still show x-sawem-mpid as
shorthand. Production authentication is §2.
12.1 Current credit-cover requirement vs posted cover
GET /api/v1/registry/settlement/credit-cover/current
Returns your current credit-cover requirement, posted cover and headroom (§15).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Responses
- 200
CreditCover— Current credit-cover position. - 404
Example — what you are doing
You are reading
current credit-cover requirement vs posted cover for the
identifiers in the path.
GET /api/v1/registry/settlement/credit-cover/current HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — no in-app HTTP caller. Parallel UI: reconciliation / statement views under
ReconciliationLive/org/brp/reconciliationand MO billing board. MonthlyWB.Brp.Workers.ReconcileMonthon the 3rd at 07:00 uses MoGateway. This is market §15 settlement — not the PPA ledger in V8. V9 §15.
12.2 Invoice / self-billing invoice for a billing period
GET /api/v1/registry/settlement/invoices/:billing_period
Returns your invoice or self-billing invoice for the billing period (§15).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
billing_period |
string | required | Billing period start date (typically the first calendar day of the month, SAST). |
Responses
- 200
SettlementInvoice— Your invoice for the billing period. - 404
Example — what you are doing
You are reading
invoice / self-billing invoice for a billing period for the
identifiers in the path.
GET /api/v1/registry/settlement/invoices/2026-07-01 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — no in-app HTTP caller. Parallel UI: reconciliation / statement views under
ReconciliationLive/org/brp/reconciliationand MO billing board. MonthlyWB.Brp.Workers.ReconcileMonthon the 3rd at 07:00 uses MoGateway. This is market §15 settlement — not the PPA ledger in V8. V9 §15.
12.3 Get a settlement query / dispute by id
GET /api/v1/registry/settlement/queries/:query_id
Returns a settlement query or dispute you previously opened (§15, API-SPEC §6.4).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
query_id |
string | required | Settlement query / dispute identifier previously issued to your party. |
Responses
- 200 — Settlement query status and detail.
- 404
Example — what you are doing
You are reading get a settlement query / dispute by id
for the identifiers in the path.
GET /api/v1/registry/settlement/queries/Q-1001 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — no in-app HTTP caller. Parallel UI: reconciliation / statement views under
ReconciliationLive/org/brp/reconciliationand MO billing board. MonthlyWB.Brp.Workers.ReconcileMonthon the 3rd at 07:00 uses MoGateway. This is market §15 settlement — not the PPA ledger in V8. V9 §15.
12.4 Financial statement for a billing period
GET /api/v1/registry/settlement/statements/:billing_period
Returns your financial statement for the billing period (§15).
| Auth | Party (ParticipantMtlsOAuth) — Bearer JWT; see §2. Samples use
x-sawem-mpid as shorthand |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
billing_period |
string | required | Billing period start date (typically the first calendar day of the month, SAST). |
Responses
- 200
SettlementStatement— Your statement for the billing period. - 404
Example — what you are doing
You are reading financial statement for a billing period
for the identifiers in the path.
GET /api/v1/registry/settlement/statements/2026-07-01 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Authorization: Bearer <token>
x-sawem-mpid: BRP001
Who calls this. External BRP clients — no in-app HTTP caller. Parallel UI: reconciliation / statement views under
ReconciliationLive/org/brp/reconciliationand MO billing board. MonthlyWB.Brp.Workers.ReconcileMonthon the 3rd at 07:00 uses MoGateway. This is market §15 settlement — not the PPA ledger in V8. V9 §15.
13. Events and publication
Public event feed and §16 publication documents (data-exchange, OpenAPI, formulation, audit pack).
13.1 Event feed (SSE or JSON poll)
GET /api/v1/events
One path, two transports: Server-Sent Events when you
Accept: text/event-stream, otherwise a JSON page (§6.5,
§16(2)(f)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
since |
string | optional | Replay events at or after this SAST timestamp. |
limit |
integer | optional | Close the SSE stream after this many events (harness convenience). |
Responses
- 200
EventPage— JSONEventPagewhen not streaming; otherwisetext/event-streamchunks with the same event ids. - 404
Example — what you are doing
You are reading event feed (sse or json poll) for the
identifiers in the path.
GET /api/v1/events HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External / public clients — UI uses domain, not this HTTP path. No in-app HTTP caller. Parallel screen: public Price board
Public.PriceBoardLiveat/prices(viaMo.Publicationdomain). MO boards also read domain publications. External BRPs and websites may call this API.
13.2 Bi-annual §16(4) audit pack
GET /api/v1/publication/audit
Returns the bi-annual IT / software audit scope and evidence pack (§16(4)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
period |
string | optional | Audit period identifier / start date to retrieve. |
Responses
- 200 — Audit scope and evidence pack.
- 404
Example — what you are doing
You are reading bi-annual §16(4) audit pack for the
identifiers in the path.
GET /api/v1/publication/audit HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External / public machine clients — no in-app HTTP caller. Served for external readers and auditors. The org UI never GETs these over HTTP to render a screen. Pedagogy for data-exchange lives in V9 §17.
13.3 §16 data-exchange document
GET /api/v1/publication/data-exchange
Returns the Market Code §16(1),(2) data-exchange document the MO maintains on its website.
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Responses
- 200
DataExchangeDocument— Published §16 document. - 404
Example — what you are doing
You are reading §16 data-exchange document for the
identifiers in the path.
GET /api/v1/publication/data-exchange HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External / public machine clients — no in-app HTTP caller. Served for external readers and auditors. The org UI never GETs these over HTTP to render a screen. Pedagogy for data-exchange lives in V9 §17.
13.4 Published §9.5(7) scheduling formulation
GET /api/v1/publication/formulation
Returns the generic specification of the scheduling algorithm the MO publishes (§9.5(7), §16(2)(h)).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Responses
- 200 — Published formulation and comment window.
- 404
Example — what you are doing
You are reading published §9.5(7) scheduling formulation
for the identifiers in the path.
GET /api/v1/publication/formulation HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External / public machine clients — no in-app HTTP caller. Served for external readers and auditors. The org UI never GETs these over HTTP to render a screen. Pedagogy for data-exchange lives in V9 §17.
13.5 OpenAPI description of the market interface
GET /api/v1/publication/openapi
Returns this OpenAPI 3.1 document, generated from the router so served routes and published paths cannot drift (§16).
| Auth | Public open data (PublicOpenData) — send
X-Sawem-Market-Code-Version: 2.3 |
| Idempotency-Key | Not used on GET |
Responses
- 200
OpenApiDocument— OpenAPI 3.1 document. - 404
Example — what you are doing
You are reading
openapi description of the market interface for the
identifiers in the path.
GET /api/v1/publication/openapi HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. External / public machine clients — no in-app HTTP caller. Served for external readers and auditors. The org UI never GETs these over HTTP to render a screen. Pedagogy for data-exchange lives in V9 §17.
Signed webhook delivery
Subscriptions persist in PostgreSQL. Creation and rotation return a
generated whsec_ secret once; GET never returns it. During
the first 24 hours after rotation, verify either signature. The platform
uses the Standard
Webhooks v1 specification.
Verify webhook-signature by computing HMAC-SHA256 over
the exact bytes webhook-id.webhook-timestamp.body, using
the base64-decoded secret after whsec_. Compare
v1,<base64 digest> securely. Reject timestamps more
than five minutes from your clock; use the stable event ID to
deduplicate retries. Do not reserialize the body before verifying.
POST /subscriptions/:id/rotate-secret rotates;
GET /subscriptions/:id/deliveries lists recent attempt
outcomes and accepts a status filter;
POST /subscriptions/:id/deliveries/:delivery_id/retry
retries a dead letter. IDs outside the caller’s party return 404.
Payloads above 20 KB carry a reference. GET /events?since=
and its SSE transport remain the polling/replay surface.
14. Internal MO–SO
Operator-to-operator contract resources. Not for BRPs.
Mutual TLS is enforced on the dedicated API listener: a client
certificate whose SHA-256 fingerprint matches the configured
system_operator or market_operator identity.
X-Sawem-Internal-Party is sandbox/test-only — the same two
exemptions that retired x-sawem-mpid on the participant
surface (§2). Per-endpoint
Auth rows already say mTLS
InternalParty.
Live source: filter tags containing Internal
MO-SO in GET /api/v1/publication/openapi.
14.1 Report fallbacks applied for a Trading Day
GET /internal/fallbacks/:trading_date
Returns which SO→MO inputs were missing and which published fallbacks the MO applied (API-SPEC §8.3, §16(2)(f)).
| Auth | Internal (InternalParty) —
X-Sawem-Internal-Party: system_operator|market_operator |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Query parameters
| Name | Type | Notes | |
|---|---|---|---|
missing |
string | optional | Comma-separated input keys to focus the fallback report. |
Responses
- 200 — Fallbacks applied for the Trading Day.
- 404
Example — what you are doing
You are reading
report fallbacks applied for a trading day for the
identifiers in the path.
GET /internal/fallbacks/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
X-Sawem-Internal-Party: market_operator
Who calls this. Internal MO ↔︎ SO contract — not for BRPs. Called by the Market Operator / System Operator integration layer (mTLS
InternalParty), and by conformance tests. No BRP LiveView and no Oban BRP worker hits these paths. SO console (/so) and MO console (/mo) use domain modules, not this HTTP surface.
14.2 Get an MO→SO contract resource
GET /internal/mo/:resource
Returns a Market Operator → System Operator contract resource (API-SPEC §8.2).
| Auth | Internal (InternalParty) —
X-Sawem-Internal-Party: system_operator|market_operator |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
resource |
string | required | Internal MO→SO contract resource key (API-SPEC §8.2), e.g. a schedule or reserve requirement artefact. |
Responses
- 200 — Requested MO→SO resource payload.
- 404
Example — what you are doing
You are reading get an mo→so contract resource for the
identifiers in the path.
GET /internal/mo/schedules HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
X-Sawem-Internal-Party: market_operator
Who calls this. Internal MO ↔︎ SO contract — not for BRPs. Called by the Market Operator / System Operator integration layer (mTLS
InternalParty), and by conformance tests. No BRP LiveView and no Oban BRP worker hits these paths. SO console (/so) and MO console (/mo) use domain modules, not this HTTP surface.
14.3 Get an MO→SO contract resource
GET /internal/mo/:resource/:trading_date
Returns a Market Operator → System Operator contract resource (API-SPEC §8.2).
| Auth | Internal (InternalParty) —
X-Sawem-Internal-Party: system_operator|market_operator |
| Idempotency-Key | Not used on GET |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
resource |
string | required | Internal MO→SO contract resource key (API-SPEC §8.2), e.g. a schedule or reserve requirement artefact. |
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200 — Requested MO→SO resource payload.
- 404
Example — what you are doing
You are reading get an mo→so contract resource for the
identifiers in the path.
GET /internal/mo/schedules/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
X-Sawem-Internal-Party: market_operator
Who calls this. Internal MO ↔︎ SO contract — not for BRPs. Called by the Market Operator / System Operator integration layer (mTLS
InternalParty), and by conformance tests. No BRP LiveView and no Oban BRP worker hits these paths. SO console (/so) and MO console (/mo) use domain modules, not this HTTP surface.
14.4 Put/patch an SO→MO contract input
PUT /internal/so/:input
Accepts a System Operator → Market Operator contract input (API-SPEC §8.1).
| Auth | Internal (InternalParty) —
X-Sawem-Internal-Party: system_operator|market_operator |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
input |
string | required | Internal SO→MO contract input key (API-SPEC §8.1), e.g. a demand forecast or constraint set name. |
Responses
- 200
InternalPutAccepted— Input accepted (possibly late). - 202
InternalPutAccepted— Input accepted for asynchronous application. - 404
Example — what you are doing
You are calling PUT to put/patch an SO→MO contract
input.
PUT /internal/so/constraints HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
X-Sawem-Internal-Party: market_operator
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. Internal MO ↔︎ SO contract — not for BRPs. Called by the Market Operator / System Operator integration layer (mTLS
InternalParty), and by conformance tests. No BRP LiveView and no Oban BRP worker hits these paths. SO console (/so) and MO console (/mo) use domain modules, not this HTTP surface.
14.5 Put/patch an SO→MO contract input
PATCH /internal/so/:input/:trading_date
Accepts a System Operator → Market Operator contract input (API-SPEC §8.1).
| Auth | Internal (InternalParty) —
X-Sawem-Internal-Party: system_operator|market_operator |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
input |
string | required | Internal SO→MO contract input key (API-SPEC §8.1), e.g. a demand forecast or constraint set name. |
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200
InternalPutAccepted— Input accepted (possibly late). - 202
InternalPutAccepted— Input accepted for asynchronous application. - 404
Example — what you are doing
You are calling PATCH to put/patch an SO→MO contract
input.
PATCH /internal/so/constraints/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
X-Sawem-Internal-Party: market_operator
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. Internal MO ↔︎ SO contract — not for BRPs. Called by the Market Operator / System Operator integration layer (mTLS
InternalParty), and by conformance tests. No BRP LiveView and no Oban BRP worker hits these paths. SO console (/so) and MO console (/mo) use domain modules, not this HTTP surface.
14.6 Put/patch an SO→MO contract input
PUT /internal/so/:input/:trading_date
Accepts a System Operator → Market Operator contract input (API-SPEC §8.1).
| Auth | Internal (InternalParty) —
X-Sawem-Internal-Party: system_operator|market_operator |
| Idempotency-Key | Required on this unsafe method |
| Request body | object |
Path parameters
| Name | Type | Notes | |
|---|---|---|---|
input |
string | required | Internal SO→MO contract input key (API-SPEC §8.1), e.g. a demand forecast or constraint set name. |
trading_date |
string | required | Trading Day on the SAST calendar (YYYY-MM-DD). Market
clocks and gates are evaluated against this date, not your local |
Responses
- 200
InternalPutAccepted— Input accepted (possibly late). - 202
InternalPutAccepted— Input accepted for asynchronous application. - 404
Example — what you are doing
You are calling PUT to put/patch an SO→MO contract
input.
PUT /internal/so/constraints/2026-07-09 HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
X-Sawem-Internal-Party: market_operator
Idempotency-Key: 018f-demo-key-0001
Content-Type: application/json
{
/* see schema `object` in OpenAPI components */
}
Who calls this. Internal MO ↔︎ SO contract — not for BRPs. Called by the Market Operator / System Operator integration layer (mTLS
InternalParty), and by conformance tests. No BRP LiveView and no Oban BRP worker hits these paths. SO console (/so) and MO console (/mo) use domain modules, not this HTTP surface.
15. Sandbox
Sandbox operations are defined in the OpenAPI catalogue and mounted
only when
Application.compile_env(:wb_wheeling, :sawem_sandbox) is
true (currently the test environment). They must
never be exposed on a market whose clock a caller can
freeze.
Who calls these. Sandbox / conformance only. No production UI or cron. Used by
test/conformance/*and golden-day harnesses.
15.1 Read the sandbox market clock
GET /api/v1/sandbox/clock
| Auth | PublicOpenData class (sandbox) |
Example — what you are doing
You are calling the sandbox control plane: read the sandbox market clock.
GET /api/v1/sandbox/clock HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. Sandbox / conformance only. Not mounted in normal production compiles. No LiveView invokes these routes.
15.2 Freeze the sandbox clock at an instant
PUT /api/v1/sandbox/clock
| Auth | PublicOpenData class (sandbox) |
| Idempotency-Key | Required |
Example — what you are doing
You are pinning the market clock so conformance scenarios are reproducible.
PUT /api/v1/sandbox/clock HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Idempotency-Key: 018f-sandbox-1
Content-Type: application/json
{
"at": "2026-07-09T10:00:00+02:00"
}
Who calls this. Sandbox / conformance only. Not mounted in normal production compiles. No LiveView invokes these routes.
15.3 Advance a frozen sandbox clock
POST /api/v1/sandbox/clock/advance
| Auth | PublicOpenData class (sandbox) |
| Idempotency-Key | Required |
Example — what you are doing
You are moving a frozen clock forward by an exact number of seconds.
POST /api/v1/sandbox/clock/advance HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Idempotency-Key: 018f-sandbox-1
Content-Type: application/json
{
"seconds": 3600
}
Who calls this. Sandbox / conformance only. Not mounted in normal production compiles. No LiveView invokes these routes.
15.4 Release the sandbox clock back to wall time
DELETE /api/v1/sandbox/clock
| Auth | PublicOpenData class (sandbox) |
| Idempotency-Key | Required |
Example — what you are doing
You are calling the sandbox control plane: release the sandbox clock back to wall time.
DELETE /api/v1/sandbox/clock HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Idempotency-Key: 018f-sandbox-1
Content-Type: application/json
Who calls this. Sandbox / conformance only. Not mounted in normal production compiles. No LiveView invokes these routes.
15.5 Reset sandbox idempotency cache and clock
POST /api/v1/sandbox/reset
| Auth | PublicOpenData class (sandbox) |
| Idempotency-Key | Required |
Example — what you are doing
You are clearing idempotency keys and releasing the clock between test cases.
POST /api/v1/sandbox/reset HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Idempotency-Key: 018f-sandbox-1
Content-Type: application/json
Who calls this. Sandbox / conformance only. Not mounted in normal production compiles. No LiveView invokes these routes.
15.6 Publish canonical and golden-day reference vectors
GET /api/v1/sandbox/reference-vectors
| Auth | PublicOpenData class (sandbox) |
Example — what you are doing
You are calling the sandbox control plane: publish canonical and golden-day reference vectors.
GET /api/v1/sandbox/reference-vectors HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. Sandbox / conformance only. Not mounted in normal production compiles. No LiveView invokes these routes.
15.7 Publish the conformance suite and CoC checklist
GET /api/v1/sandbox/conformance
| Auth | PublicOpenData class (sandbox) |
Example — what you are doing
You are calling the sandbox control plane: publish the conformance suite and coc checklist.
GET /api/v1/sandbox/conformance HTTP/1.1
Host: market.example
X-Sawem-Market-Code-Version: 2.3
Who calls this. Sandbox / conformance only. Not mounted in normal production compiles. No LiveView invokes these routes.
15.8 Published test client credentials
GET /api/v1/sandbox/reference-vectors includes an
oauth object — client_id
SANDBOX-OAUTH-CLIENT, a published throwaway
client_secret, token_url
/api/v1/oauth/token, and grant_type
client_credentials. A real integrator rehearses the exact
credential shape production requires, not a fictional shortcut.
Conformance test 21 (API-SPEC §10, clause
ParticipantMtlsOAuth): a client-credentials grant against
that published secret returns a token that authenticates the party; an
expired or wrong-audience token does not. The other twenty tests still
use the sandbox header path — authentication is not what they
assert.
The header remains valid inside the sandbox. Outside
it, and outside :sql_sandbox, x-sawem-mpid
alone is header_authentication_retired. See §2.
16. Endpoint index
Complete inventory from the live OpenAPI export used to build this volume (70 operations). Sandbox routes appear in the catalogue and in §15 even when not mounted on this compile.
Party-scoped samples later in this volume still show
x-sawem-mpid as illustrative shorthand. Production auth is
§2.
| Method | Path | Summary | Tag |
|---|---|---|---|
GET |
/api/v1/balancing/prices/:trading_date |
Published balancing prices and anonymised stacks | Balancing |
GET |
/api/v1/billing/documents |
List your billing documents | Financial settlement |
GET |
/api/v1/billing/documents/:number |
Show one of your billing documents | Financial settlement |
GET |
/api/v1/billing/registers |
List your received billing register | Financial settlement |
GET |
/api/v1/dam/adequacy-report/:trading_date |
Contingency-reserve adequacy report | Day-ahead market |
GET |
/api/v1/dam/prices/:trading_date |
Published day-ahead system prices | Day-ahead market |
GET |
/api/v1/dam/schedules/:trading_date |
Published day-ahead schedules | Day-ahead market |
GET |
/api/v1/events |
Event feed (SSE or JSON poll) | Events |
GET |
/api/v1/idm/prices/:trading_date |
Published anonymised IDM prices | Intraday market |
POST |
/api/v1/oauth/token |
Issue an OAuth2 client-credentials access token | Authentication |
GET |
/api/v1/publication/audit |
Bi-annual §16(4) audit pack | Publication |
GET |
/api/v1/publication/data-exchange |
§16 data-exchange document | Publication |
GET |
/api/v1/publication/formulation |
Published §9.5(7) scheduling formulation | Publication |
GET |
/api/v1/publication/openapi |
OpenAPI description of the market interface | Publication |
GET |
/api/v1/registry/accession-register |
Public accession register | Party registry |
POST |
/api/v1/registry/availability-revisions/:trading_date/:tuid |
Post an availability revision | Dispatch |
GET |
/api/v1/registry/balancing/balancing-groups/:group_id/:trading_date |
Balancing legs for a Balancing Group | Balancing |
GET |
/api/v1/registry/balancing/trading-units/:tuid/:trading_date |
Balancing legs for a Trading Unit | Balancing |
GET |
/api/v1/registry/dam/gate/:trading_date |
Day-ahead gate state for a Trading Day | Day-ahead market |
GET |
/api/v1/registry/dam/settlement/:trading_date |
Own day-ahead settlement lines for a Trading Day | Day-ahead market |
GET |
/api/v1/registry/dam/submissions/:trading_date/:tuid |
Get your day-ahead submission | Day-ahead market |
PUT |
/api/v1/registry/dam/submissions/:trading_date/:tuid |
Put (full-replace) a day-ahead submission | Day-ahead market |
POST |
/api/v1/registry/dam/submissions/:trading_date/validate |
Validate a day-ahead submission without storing it | Day-ahead market |
GET |
/api/v1/registry/dam/unit-prices/:trading_date/:tuid |
Own-unit day-ahead prices and opportunity costs | Day-ahead market |
GET |
/api/v1/registry/idm/auctions/:trading_date |
List IDM auction iterations for a Trading Day | Intraday market |
GET |
/api/v1/registry/idm/redeclarations/:trading_date/:tuid |
Get your IDM re-declarations | Intraday market |
PUT |
/api/v1/registry/idm/redeclarations/:trading_date/:tuid |
Put an intraday re-declaration | Intraday market |
PUT |
/api/v1/registry/idm/rescheduling-consent/:trading_date/:tuid |
Put IDM rescheduling consent | Intraday market |
GET |
/api/v1/registry/idm/schedules/:trading_date |
Own IDM schedules for a Trading Day | Intraday market |
GET |
/api/v1/registry/idm/settlement/:trading_date |
Own IDM settlement for a Trading Day | Intraday market |
GET |
/api/v1/registry/instructed-energy/:trading_date |
Instructed Energy with calculation trace | Dispatch |
POST |
/api/v1/registry/instructions/:external_ref/acknowledge |
Acknowledge a dispatch instruction | Dispatch |
GET |
/api/v1/registry/instructions/:trading_date |
List dispatch instructions for a Trading Day | Dispatch |
GET |
/api/v1/registry/metering/allocation-exceptions/:trading_date |
Allocation exceptions for a Trading Day | Metering |
GET |
/api/v1/registry/metering/points-of-delivery/:pod_id/:trading_date |
Meter / Actual Energy for a Point of Delivery | Metering |
POST |
/api/v1/registry/metering/readings |
Submit a Network-Operator meter reading batch | Metering |
GET |
/api/v1/registry/metering/trading-units/:tuid/:trading_date |
Actual Energy for a Trading Unit | Metering |
GET |
/api/v1/registry/network-zones |
List Network Zones in the published model | Network zones |
GET |
/api/v1/registry/network-zones/:code |
Show one Network Zone by code | Network zones |
POST |
/api/v1/registry/network-zones/allocate |
Dry-run Network Zone allocation for a coordinate | Network zones |
GET |
/api/v1/registry/network-zones/gaps |
List locations the zone model does not cover | Network zones |
GET |
/api/v1/registry/participants/:mpid |
Show your party record | Party registry |
GET |
/api/v1/registry/participants/:mpid/balancing-groups |
List your Balancing Groups | Party registry |
POST |
/api/v1/registry/participants/:mpid/balancing-groups |
Create a Balancing Group | Party registry |
PATCH |
/api/v1/registry/balancing-groups/:id |
Amend a Balancing Group (new row) | Party registry |
DELETE |
/api/v1/registry/balancing-groups/:id |
Cancel a Balancing Group | Party registry |
GET |
/api/v1/registry/participants/:mpid/notices |
List your default notices and suspension orders | Party registry |
GET |
/api/v1/registry/participants/:mpid/trading-units |
List your Trading Units | Party registry |
POST |
/api/v1/registry/participants/:mpid/trading-units |
Register a Trading Unit | Party registry |
DELETE |
/api/v1/registry/points-of-delivery/:pod_id |
Delete (end-date) a Point of Delivery | Party registry |
GET |
/api/v1/registry/settlement/credit-cover/current |
Current credit-cover requirement vs posted cover | Financial settlement |
GET |
/api/v1/registry/settlement/invoices/:billing_period |
Invoice / self-billing invoice for a billing period | Financial settlement |
GET |
/api/v1/registry/settlement/queries/:query_id |
Get a settlement query / dispute by id | Financial settlement |
GET |
/api/v1/registry/settlement/statements/:billing_period |
Financial statement for a billing period | Financial settlement |
GET |
/api/v1/registry/trading-units/:tuid |
Show one Trading Unit | Party registry |
GET |
/api/v1/registry/trading-units/:tuid/energy-constrained-profile |
Show energy-constrained profile (§7.3) | Standing data |
PUT |
/api/v1/registry/trading-units/:tuid/energy-constrained-profile |
Replace energy-constrained profile (§7.3) | Standing data |
POST |
/api/v1/registry/trading-units/:tuid/modifications |
Request a §7.1(5) Trading Unit modification | Party registry |
GET |
/api/v1/registry/trading-units/:tuid/points-of-delivery |
List Points of Delivery on a Trading Unit | Party registry |
POST |
/api/v1/registry/trading-units/:tuid/points-of-delivery |
Register a Point of Delivery | Party registry |
GET |
/api/v1/registry/trading-units/:tuid/reserve-certifications |
List reserve certifications for a Trading Unit | Standing data |
POST |
/api/v1/registry/trading-units/:tuid/reserve-certifications |
Request a reserve certification | Standing data |
GET |
/api/v1/registry/trading-units/:tuid/standing-data |
Show standing data for a Trading Unit | Standing data |
PATCH |
/api/v1/registry/trading-units/:tuid/standing-data |
Patch standing data for a Trading Unit | Standing data |
GET |
/api/v1/registry/trading-units/:tuid/storage-profile |
Show storage profile (§7.4) | Standing data |
PUT |
/api/v1/registry/trading-units/:tuid/storage-profile |
Replace storage profile (§7.4) | Standing data |
GET |
/internal/fallbacks/:trading_date |
Report fallbacks applied for a Trading Day | Internal MO-SO |
GET |
/internal/mo/:resource |
Get an MO→SO contract resource | Internal MO-SO |
GET |
/internal/mo/:resource/:trading_date |
Get an MO→SO contract resource | Internal MO-SO |
PUT |
/internal/so/:input |
Put/patch an SO→MO contract input | Internal MO-SO |
PATCH |
/internal/so/:input/:trading_date |
Put/patch an SO→MO contract input | Internal MO-SO |
PUT |
/internal/so/:input/:trading_date |
Put/patch an SO→MO contract input | Internal MO-SO |
Sandbox paths
(catalogue; mount when :sawem_sandbox)
| Method | Path | Summary |
|---|---|---|
GET |
/api/v1/sandbox/clock |
Read the sandbox market clock |
PUT |
/api/v1/sandbox/clock |
Freeze the sandbox clock |
POST |
/api/v1/sandbox/clock/advance |
Advance a frozen clock |
DELETE |
/api/v1/sandbox/clock |
Release clock to wall time |
POST |
/api/v1/sandbox/reset |
Reset idempotency + clock |
GET |
/api/v1/sandbox/reference-vectors |
Reference vectors |
GET |
/api/v1/sandbox/conformance |
Conformance + CoC checklist |
Foundation Stage 11 additions
| Method | Path | Summary |
|---|---|---|
| POST | /api/v1/telemetry/samples |
Submit the owner’s device evidence (§17) |
| GET | /api/v1/telemetry/feeds |
Ownership/consent-scoped plant feeds (§17) |
| GET | /api/v1/telemetry/feeds/:plant_feed_id/samples/:trading_date |
Scoped device samples (§17) |
17. Plant telemetry
Telemetry is a device-evidence API, separate from meter imports. It
uses the participant API’s OAuth bearer, HMAC and idempotency pipeline.
A current active registration needs telemetry:push to
submit its own plant data and telemetry:read to read a
feed. Read consent never confers write permission.
| Method | Path | Result |
|---|---|---|
| POST | /api/v1/telemetry/samples |
202 with batch ID, accepted count and row rejections |
| GET | /api/v1/telemetry/feeds |
Feed register limited by ownership or current consent |
| GET | /api/v1/telemetry/feeds/:plant_feed_id/samples/:trading_date |
Samples for a SAST trading date, with
x-telemetry-freshness |
17.1 A push
Send JSON with Content-Type: application/json, a bearer
token and an Idempotency-Key. Use the shared API signing
headers when a feed requires a signature. A batch holds 1–288 samples
spanning less than 24 hours, with one row per feed bucket.
{
"schema_version": "telemetry.samples.v1",
"plant_feed_id": "<registered-uuid>",
"samples": [{
"sampled_at": "2026-08-18T11:00:00+02:00",
"active_power_kw": "7980.000",
"available_capacity_kw": "20000.000",
"setpoint_kw": "8000.000",
"setpoint_pct": "40.000",
"curtailment_mode": true,
"status": "CURTAILED"
}]
}Use explicit numeric timezone offsets; bare Z is refused
by this API contract. Power is in kW. Decimal quantities use strings.
Optional solar, wind and battery columns match the downloadable mirror
schema. Unknown fields are retained in extras, never
treated as settlement inputs.
17.2 Refusals and replay
Pushes are limited to 120 per registration per minute, without market-gate grace. A 429 response carries retry timing. Missing or insufficient bearer scopes return 401; a foreign feed returns 404, including a consented reader attempting to push. Signature failures use the shared 401 envelope. Reusing an idempotency key with different content returns 409. Invalid schema, timestamps, batch size, duplicate buckets, grain, future time and out-of-range percentages return 422 when the entire submission is refused. Partial acceptance lists the rejected rows.
The feed-and-content identity also prevents duplicate batches beyond the API idempotency window. Changed sample values or quality produce a revision and a revision event. The original raw body remains available in its immutable batch artifact. A trace copies its samples, so later corrections cannot change published evidence.
