I figured I would drop this here in case anyone else runs into the same situation.
If you need to create multiple Emergency Number rules via the 3CX XAPI, you can do it in bulk using Postman and a CSV file.
Create a CSV with the following headers: ext, did, priority, trunk_id, prepend
- ext is the extension the rule applies to
- did should be in E.164 format
- priority must be unique across emergency rules
- trunk_id can be found in the trunk URI under 'Voice & Chat' (mypbx.3cx.us/#/office/voice-and-chat/trunk/edit/137)
- prepend you may not need, but I needed to add the SIP information for my provider
Create a new collection and configure:
- Authorization (OAuth2 / client credentials)
- Required headers (at least Content-Type: application/json) as this avoids Runner getting stuck parsing unrelated requests.
Create a request:
- POST {{base_url}}/xapi/v1/OutboundRules
- You can set the body from raw to JSON, and leave it as {} (it will be overwritten by the script).
Add this Pre-request Script and it reads values from the CSV, builds the JSON payload, and posts it as an emergency rule:
JavaScript:
console.log("CSV row:", pm.iterationData.toObject());
const ext = pm.iterationData.get("ext");
const did = pm.iterationData.get("did");
const priorityRaw = pm.iterationData.get("priority");
const trunkRaw = pm.iterationData.get("trunk_id");
const prepend = pm.iterationData.get("prepend");
const priority = Number(priorityRaw);
const trunk_id = Number(trunkRaw);
if (!ext || !did || !prepend || !Number.isFinite(priority) || !Number.isFinite(trunk_id)) {
throw new Error(
`Missing/invalid CSV value(s): ext=${ext}, did=${did}, priority=${priorityRaw}, trunk_id=${trunkRaw}, prepend=${prepend}`
);
}
const payload = {
Name: `911 for extension ${ext}`,
Prefix: "911",
Priority: priority,
NumberLengthRanges: "3",
EmergencyRule: true,
Routes: [
{
TrunkId: trunk_id,
StripDigits: 0,
Prepend: prepend,
Append: "",
CallerID: did
}
],
DNRanges: [{ From: String(ext), To: String(ext) }]
};
pm.request.headers.upsert({ key: "Content-Type", value: "application/json" });
pm.request.body.update(JSON.stringify(payload));
console.log("Payload:", payload);
Run the collection:
- Open Runner
- Select only this collection
- Attach the CSV file
- In Preview, make sure the CSV columns are split correctly. You may have to change
did and
prepend to string instead of auto-detect so you can see the e.194 format.
- Run the collection
Key gotchas to be aware of:
- Priorities must be unique or the API will return HTTP 400
- DN ranges must not overlap existing emergency rules
- Using a new collection avoids Runner getting stuck at “Preparing…”
- Test with one or two DIDs first before adding ALL of them
Hopefully this saves someone else a few hours of trial and error.