> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adipredictstreet.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pausing Trading Around Maintenance

> A worked recipe for market makers: detect an announced window early enough to act on it, know what still works while it runs, and resume on the right signal.

This is the integration recipe. For the full contract — every field, every error
code, the email behaviour — see
[Maintenance notifications](/concepts/partners/maintenance-notifications).

## What you are trying to do

Know that a window is coming early enough to do whatever your side does about
it — pull quotes, flatten, hand over to another venue, page someone — then sit
it out and resume when the platform is back.

What you do with the warning is yours. This page is about getting the signal
right and at the right time.

Two endpoints give you everything you need, and they answer different
questions. Use both — neither replaces the other.

| | Question it answers | When you read it |
| - | - | - |
| `GET /api/platform/maintenance` | *What is coming, and when?* | Slow poll, to plan |
| `GET /api/platform/status` | *What is true right now?* | Faster poll, to act |

Both take your partner API key in `X-Api-Key`.

> [!NOTE]
>
> Plan from the **schedule**. Act on the **status**. The two can disagree for a
> few minutes, and the section on [when they disagree](#when-the-two-disagree)
> explains why that is normal rather than a bug.

***

## The recipe

### 1. Poll the schedule, slowly

Once a minute is plenty — the response is cached for 5 seconds and the data
rarely changes.

```http theme={null}
GET /api/platform/maintenance?scope=trading
X-Api-Key: ps_live_<keyId>_<secret>
```

`?scope=trading` returns both `trading` windows and full-platform (`all`)
windows, because a full freeze stops trading too. A `withdrawals` window does
not affect order flow; leave the filter in place and you will not see one.

Keep the windows you get, keyed by `id`. Pass the response's `generatedAt` back
as your next `from` so you never miss a transition.

If the schedule answers `404 not_found`, or `/status` has no `maintenance`
object, the feature is not on in that environment. Treat that as "no
information", not as "all clear", and keep your own error handling.

### 2. Decide your lead time and trigger your own wind-down

Pick how much warning you need — ten minutes is a common ask. Then:

```
lead = 10 minutes

for each window you hold where status == "scheduled":
    if now >= window.startsAt - lead:
        run your wind-down
```

`run your wind-down` is whatever that means for you. Some desks stop placing
and cancel everything, some only widen, some move flow elsewhere, some just
notify a human. We do not assume which.

Announced windows normally arrive **24 hours or more** ahead, so this fires
with plenty of warning. An incident window can arrive with no notice at all —
handle that case too (see [step 5](#5-handle-the-no-notice-case)).

### 3. Know what still works while it runs

A window is an announcement, not a switch: nothing in the order path reads
it. What you see while one runs depends on the work behind it:

* **While the works are under way** (a release, a database failover), order
  placement answers `503 trading_temporarily_unavailable` or
  `503 shard_owner_unavailable`. Do not treat that as a rejected order and do
  not retry it hard. Cancels go through the same exchange and can fail the same
  way (`shard_owner_unavailable`, `exchange_unavailable`,
  `exchange_transport_error`, or `202 cancel_pending`), so the safe time to
  unwind is **before** the window starts. See
  [Errors you may see during maintenance](/concepts/partners/maintenance-notifications#errors-you-may-see-during-maintenance).
* **If the platform-wide freeze is also on** (`frozen: true` on `/status`),
  placement and `cancel-all` answer `503 platform_frozen`. Single cancel and
  `cancel-batch` stay open under the freeze by design, so you can still unwind.
* Declaring a window does not cancel your resting orders or touch your
  positions.

### 4. Resume on `status`, never on the clock

This is the part that most often gets written wrong.

```
poll GET /api/platform/status every 30s

if maintenance is present and maintenance.trading.status == "operational":
    resume quoting
```

Do **not** resume at `expectedEndAt`. That field is a promise we make to you,
not a timer:

* We can finish **early**. A window closes when we mark it complete, and that
  can be well before the time we announced.
* We sometimes run **late**. The window stays `in_progress` past
  `expectedEndAt`, and you will get an `extended` notice if we move the
  promise. Resuming on the old clock would put you back into a surface that is
  still down.

`maintenance.trading.status == "operational"` is the only signal that means
"we are back".

### 5. Handle the no-notice case

Not every outage is announced in advance. Your `/status` poll is what catches
those:

| `maintenance.trading.status` | What it means | What to do |
| - | - | - |
| `operational` | Nothing declared, and order placement is within normal limits | Quote normally |
| `degraded` | Order placement is failing more than usual. Nobody switched anything off, and no end time has been promised | Ease off your rate; retry with backoff |
| `maintenance` | Deliberately unavailable — a window is running, or a kill switch is on | Stop quoting; wait for `operational` |

`degraded` is the same alert that pages our own on-call, so you learn when we
do. There is no window id under it and no promised end, because nobody declared
it.

***

## When the two disagree

A window shows `startsAt: 19:00`, it is 19:05, and `/status` still says
`operational`. Nothing is broken.

A window becomes real when an operator presses **Start**, not when the clock
reaches `startsAt`. The announced time is when we intend to begin; the status
is what has actually happened. Start can be pressed before or after
`startsAt`, so either can come first.

What that means for you:

* **Use `startsAt` to prepare** — stop quoting, pull orders. Being flat a few
  minutes early costs you little.
* **Never infer the end from the start.** A window that has not started cannot
  end.
* **A `scheduled` window that has not started by its `expectedEndAt`
  disappears** from the feed. Until then it stays listed as `scheduled`, even
  after `startsAt`. Once it is gone it is not going to happen as announced:
  drop it and resume when `/status` says `operational`. If we later reschedule,
  start or cancel it, it reappears under the same `id`.

If a window regularly starts far from its announced time and that is costing
you, tell your account manager — we would rather tighten our side than have you
widen your lead time.

***

## Worth knowing

**One partner, one bucket per endpoint.** All of your API keys share one limit
on each endpoint — 600 requests per minute at the default rate tier — plus 600
per minute per IP (`/status` shares its IP bucket with `/notices`). The cadence
on this page, the schedule once a minute and `/status` every 30 seconds, uses 1
and 2 of those 600 respectively. See [Rate limits](/auth/rate-limits).

**Upsert by `id`.** You will be shown windows you already have for up to a
minute after they change — that overlap is deliberate, so a transition that was
mid-commit when you polled still reaches you.

**Subscribe a mailbox too.** The API is the machine signal; the email is how a
human on your side finds out. Ask your account manager to add an address — you
get a notice when a window is scheduled, rescheduled, started, extended,
completed or cancelled. See
[Email notifications](/concepts/partners/maintenance-notifications#email-notifications).

**If you cannot reach us at all**, treat it as an outage you have not been told
about: stop quoting and back off. A `401` means your key is missing or was not
accepted (malformed, unknown, revoked, expired, or called from outside its IP
allowlist), and a `403 partner_key_required` means it is a self-service key —
neither means the platform is down. These endpoints require a partner key.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.