Partner API
Order hardware, price connectivity and track fulfillment directly from your own systems — the same operations you already run in the Partner Portal, over HTTP.
Endpoints marked available are implemented, tested and safe to build against. We will not remove or rename a field on an available endpoint without telling you first.
Coverage is still growing and response times are not yet under an SLA. Please tell us what you need next — it genuinely changes the order we build in.
Quickstart
Three requests to your first order. Create a key in the Partner Portal first — keys look like mwf_live_… and are shown only once.
- 1
Verify your key
Every request carries a bearer token. This endpoint needs no permissions, so it is the quickest way to confirm a key works and see what it can reach.
curl https://api.mergewifi.com/v1/me \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
- 2
Browse your catalog
Returns the hardware available to you with your pricing. Take a product id from here for the next step.
curl https://api.mergewifi.com/v1/products \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
- 3
Look up your orders
Every order your organization has placed, newest first. Sales made through checkout sessions show up here too, and the same id works on the single-order endpoint.
curl https://api.mergewifi.com/v1/orders \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
How the API behaves
Authentication
Send Authorization: Bearer <key> on every request. Keys are shown once when created and stored only as a hash, so a lost key is replaced rather than recovered. Keys are for server-to-server use — never place one in browser or mobile app code, and this API sends no CORS headers by design.
Errors
Every failure returns the same shape: a type, a stable code, a human-readable message, and a request_id also returned in the x-request-id header. Quote that id to support and we can find the exact request. Validation failures also name the offending field in param.
Retries and duplicates
Write requests take an Idempotency-Key. Retrying with the same key returns the original result instead of creating a second record, so a timeout or dropped connection is always safe to retry. Reusing a key with genuinely different data returns 409 rather than quietly handing you the wrong record. Use a fresh UUID per operation.
Pagination
Lists use cursors. Pass limit, then follow next_cursor as starting_after while has_more is true. Cursors stay correct even when new records arrive mid-pagination, which page numbers cannot. An out-of-range limit is rejected rather than clamped, so you never silently get fewer rows than you asked for.
Rate limits
Applied per key and reported on every response via X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A 429 includes Retry-After — honour it and back off. If your integration needs a higher ceiling, ask and we will raise it.
Endpoints
Authentication
Confirm a key works and see what it can do.
/v1/meDescribe the current API key
Returns the organization, environment, and scopes the presented key carries. Requires no scopes of its own, so a misconfigured key still gets a useful answer instead of a 403.
curl https://api.mergewifi.com/v1/me \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
Catalog
The hardware and plans available to your organization, with your pricing.
/v1/productsList orderable products
The hardware available to your organization, with your pricing. Returned in full rather than paginated, so one request gives you everything you need to build a product picker. Use a product id from here when placing an order.
catalog:readcurl https://api.mergewifi.com/v1/products \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/plansList service plans
The service plans available to your organization to sell alongside hardware, with their monthly pricing. Returned in full rather than paginated, like the product catalog — one request gives you everything needed to build a picker.
catalog:readcurl https://api.mergewifi.com/v1/plans \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
Quotes
Price a basket before committing to it.
/v1/quotesPrice a basket
Returns what a basket would cost, with no side effects — nothing is created, nothing is reserved, and a quote cannot be redeemed. Call it as often as a cart changes.
Lines are itemized by kind. Read activation lines carefully: those charges are **not** in due_now and begin when the device is activated. A plan sold on warehouse-shipped hardware always defers this way, because its service line does not exist until fulfillment picks a unit and its serial is known. Hardware the customer already holds (source: "provided") bills its plan today instead.
Amounts are estimates. The authoritative figure is totals.due_now on a checkout session.
quotes:writecurl https://api.mergewifi.com/v1/quotes \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"packages": [
{
"package_id": "pkg_1",
"device": {
"product_id": "1",
"quantity": 1,
"billing": "purchase",
"source": "warehouse"
},
"plan": {
"plan_id": "12"
},
"addons": []
}
],
"shipping_address": {
"line1": "100 Congress Ave",
"city": "Austin",
"state": "TX",
"postal_code": "78701"
}
}'Field types in openapi.json
Orders
Place hardware orders and track their status.
/v1/ordersList orders
Your organization's orders, newest first. Line items are omitted to keep responses small — fetch a single order to see them.
orders:read| Parameter | Description |
|---|---|
limitquery | Rows to return, 1–100. Defaults to 25. Out-of-range values are rejected rather than clamped, so a client cannot silently receive fewer rows than it asked for. |
starting_afterquery | Opaque cursor from a previous response's next_cursor. Cursors rather than page numbers: rows inserted between requests would shift an offset and silently skip records. |
statusquery | Exact match on order status, e.g. pending, processing, cancelled. |
order_typequery | Exact match, e.g. residential, business, iot, wholesale. Orders placed in the Partner Portal may carry other values, so this is matched literally rather than restricted to a fixed list — a value with no matches returns an empty list rather than an error. |
curl https://api.mergewifi.com/v1/orders \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/orders/{id}Retrieve an order
A single order with its line items, including any devices and plans on it. Orders are scoped to your organization — an id you do not own returns a 404.
orders:read| Parameter | Description |
|---|---|
idpath · required | The order id. |
curl https://api.mergewifi.com/v1/orders/<id> \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
Checkout
Point-of-sale: open a session, tokenize a card in your own front end, and settle it.
/v1/payment_configGet publishable payment credentials
The credentials your own front end needs to tokenize a card.
The billing platform accepts only an opaque, single-use nonce, and that nonce can only be minted by the payment gateway's browser SDK — so a card must be tokenized in a browser. These values let it be tokenized in **your** browser, against our gateway, which means card details never reach your servers or ours.
Fetch this from your backend, then pass client_key and api_login_id to your page and hand them to the gateway SDK as clientKey and apiLoginID. Both are publishable and safe to expose. **Your API key is not** — it must never appear in browser code, and this API sends no CORS headers, so a browser cannot call it directly.
Send payment_type_id back when settling a session.
orders:writecurl https://api.mergewifi.com/v1/payment_config \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/checkout_sessionsOpen a point-of-sale session
Starts a retail sale: creates the customer's billing account if it does not exist, registers any equipment they already hold, builds the order and prices it with tax.
**Nothing is charged.** The session returns awaiting_payment with the authoritative totals.due_now; settle it with the pay action once you have tokenized a card for exactly that amount.
Payment is a second call on purpose. A gateway nonce is single-use, so combining the two would burn one on a total you had not yet seen — and an integration has no one to re-key a card when that happens. Creating the session first means you always tokenize against the real number.
The request carries no prices: every amount is resolved from the same catalog /v1/products and /v1/plans serve.
orders:writeRequired headers
Idempotency-Key
A fresh unique value (a UUID) per sale. Replaying it with the same basket returns the original session with a 200; reusing it for a different basket is a 409.
curl https://api.mergewifi.com/v1/checkout_sessions \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"first_name": "Dana",
"last_name": "Reyes",
"email": "dana@example.com",
"phone": "5125550142"
},
"shipping_address": {
"line1": "100 Congress Ave",
"city": "Austin",
"state": "TX",
"postal_code": "78701"
},
"packages": [
{
"package_id": "pkg_1",
"device": {
"product_id": "1",
"quantity": 1,
"billing": "purchase",
"source": "warehouse"
},
"plan": {
"plan_id": "12"
},
"addons": []
}
]
}'Field types in openapi.json
/v1/checkout_sessions/{id}Retrieve a checkout session
The current state of a sale. Poll this after a timeout to find out whether a payment landed before deciding to retry it.
totals.due_now here is authoritative — it is what the billing platform will accept, and what expected_total must match when paying.
A session and an order are the same record: this id also works on GET /v1/orders/{id}, which reports what was bought rather than what is left to do.
orders:read| Parameter | Description |
|---|---|
idpath | The checkout session id. |
curl https://api.mergewifi.com/v1/checkout_sessions/<id> \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/checkout_sessions/{id}/actions/payPay a checkout session
Charges the card and submits the order. **This is the step that moves money.**
Send a nonce your front end just minted with the gateway SDK, using the credentials from GET /v1/payment_config. A nonce is single-use and short-lived: mint one per attempt and never store one.
expected_total must equal the session's current totals.due_now. It is you stating the amount you believe you are authorizing — if the total has moved, the charge is refused rather than billing a figure nobody agreed to.
On success the session is submitted. A submit_failed session **was charged** — handoff to fulfillment is being retried for you, so do not pay again. A decline returns 402 and leaves the session payable: mint a fresh nonce and call this again.
orders:write| Parameter | Description |
|---|---|
idpath | The checkout session id. |
curl https://api.mergewifi.com/v1/checkout_sessions/<id>/actions/pay \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"payment": {
"nonce": "eyJjb2RlIjoiNTBfMl8wNjAwMDUyN0…",
"data_descriptor": "COMMON.ACCEPT.INAPP.PAYMENT",
"payment_type_id": 7
},
"expected_total": "412.87"
}'Field types in openapi.json
/v1/checkout_sessions/{id}/actions/cancelCancel a checkout session
Abandons an unpaid sale and cancels the draft order behind it. Worth calling rather than walking away: an abandoned session leaves a draft order, and for provided equipment a draft service line, on the customer's account. They are harmless and a later sale reuses them, but a cancelled session is far easier to reconcile than a stalled one. Only unpaid sessions can be cancelled. Once the card has been charged this returns 409 — reversing a payment is a refund, which this API does not do.
orders:write| Parameter | Description |
|---|---|
idpath | The checkout session id. |
curl https://api.mergewifi.com/v1/checkout_sessions/<id>/actions/cancel \ -X POST \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
Devices
Inventory, configuration and lifecycle for devices on your account.
/v1/devicesList devices
The devices on your account, newest first. Filter with activated, reachable, serial, data_plan, model, or free text via q.
Rows reflect the most recent inventory sync, so a device added in the last few minutes may not appear yet; retrieving a device by id always reads current state. Usage is reported in **bytes**.
devices:read| Parameter | Description |
|---|---|
limitquery | Rows to return, 1–100. Defaults to 25. Out-of-range values are rejected rather than clamped, so a client cannot silently receive fewer rows than it asked for. |
starting_afterquery | Opaque cursor from a previous response's next_cursor. Cursors rather than page numbers: rows inserted between requests would shift an offset and silently skip records. |
activatedquery | true or false. Omit for both. |
reachablequery | true or false. Reachability is independent of activation — a device can be activated and powered off. |
serialquery | Exact match on the device serial. |
data_planquery | Exact match on the plan name, or unassigned for devices with none. |
modelquery | Exact match on the hardware model. |
qquery | Free-text search across serial, label, and id. |
curl https://api.mergewifi.com/v1/devices \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}Retrieve a device
A single device. Devices are scoped to your organization — an id you do not own returns a 404, indistinguishable from one that does not exist.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid> \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/actions/restartRestart a device
Reboots the device. It is unreachable for a minute or so afterwards.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/actions/restart \ -X POST \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/actions/activateActivate a device
Brings a device into service on a network group. Activation is billable and requires the activation capability on your account.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/actions/activate \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"network_group_id": "5"
}'Field types in openapi.json
/v1/devices/{uuid}/actions/deactivateDeactivate a device
Takes a device out of service. It remains assigned to your organization.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/actions/deactivate \ -X POST \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/actions/update_firmwareUpdate device firmware
Asks the device to fetch and apply the latest firmware. It downloads on its own schedule and is unreachable while it reboots.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/actions/update_firmware \ -X POST \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/actions/factory_resetReset a device to factory configuration
Restores the factory configuration, discarding the SSID, LAN addressing and any networking rules on the device. This cannot be undone.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/actions/factory_reset \ -X POST \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}Update a device
Changes the label, data plan, or network group. Change data_plan_id and network_group_id in SEPARATE requests — they are applied independently upstream, so a combined request could half-succeed.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid> \
-X PATCH \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Warehouse dock 3"
}'Field types in openapi.json
/v1/devices/{uuid}/wifiRetrieve Wi-Fi settings
The network name, and whether a password is set. The password itself is never returned.
Read live from the device, so a device that is powered off or out of coverage returns 409 device_unreachable — or 503 if it does not answer in time.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/wifi \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/wifiUpdate Wi-Fi settings
Applied to the hardware, so it takes effect when the device next checks in. Passwords must be at least 8 characters.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/wifi \
-X PATCH \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ssid": "Acme-Warehouse"
}'Field types in openapi.json
/v1/devices/{uuid}/networkRetrieve LAN settings
The device's LAN address and MTU.
Read live from the device, so a device that is powered off or out of coverage returns 409 device_unreachable — or 503 if it does not answer in time.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/network \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/networkUpdate LAN settings
lan_ip and mtu are applied by separate upstream calls, so a request setting both can partially succeed; the error names which one failed. MTU must be between 1000 and 1500.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/network \
-X PATCH \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mtu": 1400
}'Field types in openapi.json
/v1/devices/{uuid}/restart_scheduleSet a restart schedule
A device has at most one schedule, so this creates or replaces it. time is 24-hour HH:MM in the device's local time.
day is an integer and is required unless frequency is daily: the day of the month for a monthly schedule, and the device platform's own weekday index for a weekly one. It is passed through to the platform unchanged.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/restart_schedule \
-X PATCH \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"frequency": "daily",
"time": "03:00"
}'Field types in openapi.json
/v1/devices/{uuid}/restart_scheduleCancel the restart schedule
Idempotent — cancelling when nothing is scheduled succeeds.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/restart_schedule \ -X DELETE \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/connectivityRetrieve live connectivity
How many clients are attached, who they are, and recent uptime. Read live from the device platform rather than from synced inventory. A field is null when that source was unavailable, so a partial outage degrades the response instead of failing it.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/connectivity \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/eventsList device events
What has been done to this device, most recent first.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/events \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/notesList device notes
Notes attached to the device. The author is not returned — it is frequently a member of our own or the platform's staff.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/notes \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/notesAdd a device note
Attaches a note to the device.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/notes \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"note": "Relocated to dock 3"
}'Field types in openapi.json
/v1/devices/{uuid}/config_backupsList configuration backups
Backups taken of this device's configuration. Restoring is a support operation and is not available through the API.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/config_backups \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/config_backupsTake a configuration backup
Captures the device's current configuration. Completes asynchronously, so acceptance is not completion — poll the list endpoint. Taking a second backup is harmless, so retries are safe without an idempotency key.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/config_backups \ -X POST \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/data_plansList data plans
The data plans a device can be assigned. Distinct from /v1/plans, which lists the SERVICE plans sold to end customers.
devices:readcurl https://api.mergewifi.com/v1/data_plans \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
Device networking
Port forwarding, dedicated and bridged IP addresses.
/v1/devices/{uuid}/port_forwardsList port forwarding rules
Rules currently applied to this device.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/port_forwards \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/port_forwardsCreate a port forwarding rule
Ports must be 1-65535. protocol is TCP, UDP or BOTH; application_protocol is HTTP, HTTPS or OTHER. Returns the device's full rule set. Sending an identical rule again is a no-op, so retries are safe without an idempotency key.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/port_forwards \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inbound_ip": "203.0.113.10",
"inbound_port": 8080,
"internal_ip": "192.168.1.50",
"internal_port": 80,
"protocol": "TCP",
"application_protocol": "HTTP"
}'Field types in openapi.json
/v1/devices/{uuid}/port_forwards/{rule_id}Delete a port forwarding rule
Removes the port forwarding rule. The rule is confirmed to belong to this device first, so an id from another device returns 404.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
rule_idpath · required | The rule id, from the list endpoint. |
curl https://api.mergewifi.com/v1/devices/<uuid>/port_forwards/<rule_id> \ -X DELETE \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/dedicated_ipsList dedicated IP rules
Dedicated inbound addresses assigned to this device.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/dedicated_ips \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/dedicated_ipsAssign a dedicated IP
Returns the device's full set of dedicated addresses. Sending an identical rule again is a no-op, so retries are safe without an idempotency key.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/dedicated_ips \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inbound_ip": "203.0.113.10"
}'Field types in openapi.json
/v1/devices/{uuid}/dedicated_ips/{rule_id}Delete a dedicated IP rule
Removes the dedicated IP rule. The rule is confirmed to belong to this device first, so an id from another device returns 404.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
rule_idpath · required | The rule id, from the list endpoint. |
curl https://api.mergewifi.com/v1/devices/<uuid>/dedicated_ips/<rule_id> \ -X DELETE \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/bridged_ipsList bridged IP rules
Bridged addresses assigned to this device.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/bridged_ips \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/bridged_ipsAssign a bridged IP
Returns the device's full set of bridged addresses. Sending an identical rule again is a no-op, so retries are safe without an idempotency key.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/bridged_ips \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inbound_ip": "203.0.113.20"
}'Field types in openapi.json
/v1/devices/{uuid}/bridged_ips/{rule_id}Delete a bridged IP rule
Removes the bridged IP rule. The rule is confirmed to belong to this device first, so an id from another device returns 404.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
rule_idpath · required | The rule id, from the list endpoint. |
curl https://api.mergewifi.com/v1/devices/<uuid>/bridged_ips/<rule_id> \ -X DELETE \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/network_groupsList network groups
The network groups a device can be activated on or moved between. Take an id from here for activate or a network group change.
devices:readcurl https://api.mergewifi.com/v1/network_groups \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
Device diagnostics
Speed tests, network scans and diagnostics.
/v1/devices/{uuid}/actions/speed_testStart a speed test
Starts a speed test on the device. Results arrive asynchronously — poll the matching read endpoint.
type is rapid (the default) or full.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/actions/speed_test \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "rapid"
}'Field types in openapi.json
/v1/devices/{uuid}/speed_testsList speed test results
Completed speed test results, most recent first. The payload is returned as an opaque data object — its shape is undocumented upstream and varies by hardware model.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/speed_tests \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/actions/network_scanStart a network scan
Starts a network scan on the device. Results arrive asynchronously — poll the matching read endpoint.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/actions/network_scan \ -X POST \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/network_scansList network scan results
Completed network scan results, most recent first. The payload is returned as an opaque data object — its shape is undocumented upstream and varies by hardware model.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/network_scans \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/devices/{uuid}/actions/network_diagnosticStart a network diagnostic
Starts a network diagnostic on the device. Results arrive asynchronously — poll the matching read endpoint.
The diagnostic runs against a network group. It defaults to the one the device is on; pass network_group_id to test a different one.
devices:write| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/actions/network_diagnostic \
-X POST \
-H "Authorization: Bearer $MERGEWIFI_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'Field types in openapi.json
/v1/devices/{uuid}/network_diagnosticsList network diagnostic results
Completed network diagnostic results, most recent first. The payload is returned as an opaque data object — its shape is undocumented upstream and varies by hardware model.
devices:read| Parameter | Description |
|---|---|
uuidpath · required | The device id. |
curl https://api.mergewifi.com/v1/devices/<uuid>/network_diagnostics \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
Customers
The end customers you sell to.
/v1/customersList customers
The end customers on your account, newest first. Search across name, email and phone with q, or filter by status.
Pass an id from here as customer_id when opening a checkout session to bind the sale to that customer's existing billing account instead of matching on their email address.
customers:read| Parameter | Description |
|---|---|
limitquery | Rows to return, 1–100. Defaults to 25. Out-of-range values are rejected rather than clamped, so a client cannot silently receive fewer rows than it asked for. |
pagequery | 1-based page number. This collection pages by number rather than by cursor, so next_cursor is always null. |
qquery | Free-text match across first name, last name, email and phone. |
statusquery | Exact match, e.g. active, paused, cancelled. Customers synced from billing carry that platform's own states. |
curl https://api.mergewifi.com/v1/customers \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json
/v1/customers/{id}Retrieve a customer
One end customer on your account.
customers:read| Parameter | Description |
|---|---|
idpath | The customer id. |
curl https://api.mergewifi.com/v1/customers/<id> \ -H "Authorization: Bearer $MERGEWIFI_API_KEY"
Field types in openapi.json