Errors
Every error has the same shape:
{
"success": false,
"error": "validation_failed",
"detail": "One or more fields are invalid.",
"fields": [ { "path": "sizing.ratio", "code": "less_than_equal", "limit": 10 } ],
"meta": { "requestId": "req_9f2c1a0b7d3e4f51" }
}
erroris a stable code from the tables below. Build your logic on it.detailis a plain-English sentence you can show to a person. Its wording can change.fieldsappears on validation errors and on a few other errors that point at specific fields (for exampleaccount_not_foundon connection settings,field_lockedandswitches_locked).pathis the field (dotted for nested fields, for examplesizing.ratio),codesays what is wrong, andlimitorpatternshows the bound that was broken. The values you sent are never repeated back.retryAfter(seconds) and aRetry-Afterheader accompany429admission refusals and503 management_busy, and can accompany409 concurrent_modification. Other503errors may omit them.policynames the budget onrate_limited.meta.etagcomes with412 precondition_failedand holds the current ETag.
Request and access errors
| Status | error | Meaning | What to do |
|---|---|---|---|
| 400 | invalid_json | The body is not valid JSON, has duplicate keys, NaN/Infinity, or is nested too deeply | Fix the body |
| 400 | unexpected_body | A GET or DELETE was sent with a body | Send no body |
| 400 | unknown_parameter | An unknown or repeated query parameter | Remove it |
| 400 | invalid_path | The account name or id in the path is not valid | Check the encoding and the value |
| 401 | unauthorized | Missing, malformed or revoked token, or a disabled account | Check the Authorization: Bearer header |
| 403 | elite_required | Your plan does not include the Management API | Upgrade to Elite |
| 403 | not_available | The Management API is not open for your account yet | Contact support |
| 403 | plan_required | Your plan does not include this feature | Upgrade your plan |
| 404 | not_found | No such resource on your account, or an unknown endpoint | Check the path and id |
| 405 | method_not_allowed | The endpoint exists but not with that method. The Allow header lists the methods it takes | Use an allowed method |
| 408 | body_timeout | The body was not received within 10 seconds | Retry |
| 413 | body_too_large | The body is larger than 64 KB | Send a smaller body |
| 415 | unsupported_content_type | The body is not application/json, declares a charset other than UTF-8, or is compressed | Send uncompressed UTF-8 JSON |
| 429 | rate_limited | A budget is used up | Wait retryAfter seconds. See Rate limits |
| 429 | too_many_concurrent_requests | Two requests are already running for your account | Wait for one to finish |
| 500 | internal_error | Something went wrong on our side | Retry later; contact support with the request id |
| 503 | management_unavailable | The Management API is temporarily off | Retry later |
| 503 | management_read_only | Changes are temporarily paused; reads still work | Retry later |
| 503 | family_unavailable | This part of the API is temporarily off | Retry later |
| 503 | management_busy | The API is under heavy load | Wait retryAfter seconds |
Validation errors (422)
error | Meaning | What to do |
|---|---|---|
validation_failed | One or more fields are invalid. fields lists each problem | Fix the listed fields |
field_read_only | The body contains a field you cannot change (for example id or state) | Remove it, or send the saved value |
field_not_applicable | The field does not exist for this broker (for example a NinjaTrader-only monitor field on a Tradovate monitor) | Remove it |
immutable_field | The field can only be set when the resource is created (a monitor's account, an account group's destination) | Delete and re-create instead |
use_kill_switch_endpoint | killSwitch was sent to PATCH /controls with a value different from the saved one | Use PUT /controls/kill-switch |
invalid_replacement | A copier symbol replacement is not allowed | See the copier field reference |
invalid_atm_config | The ATM template configuration is not valid. detail names the problem and fields lists the config.* fields involved | Fix the named fields |
On a create, field_read_only and field_not_applicable refuse the field whatever its value. On a PATCH, field_read_only, immutable_field, use_kill_switch_endpoint and field_not_applicable mean the value you sent differs from what is saved: a matching value is ignored, so you can send back a resource you just read.
Common code values in fields for validation_failed:
code | Meaning |
|---|---|
required_when_days_set | The master trading window has days but no start or end |
required_when_enabled | The setting is turned on but the value it needs is missing or zero (for example a trailing drawdown with amount: 0, which would stop the account on the first tick) |
empty_window | A trading window starts and ends at the same time, which would allow trading for one minute a day |
outside_window | closingOnlyAfter is not strictly inside the master trading window (which runs past midnight when end is earlier than start) |
windows_overlap | Two enabled monitor trading windows cover the same time |
ratio_not_a_step | A copier ratio is not one of the values the web app offers (0.25 to 1.75 in steps of 0.25, then 2 to 10) |
unknown_connection | A connection name is not one of your NinjaTrader connections |
string_pattern_mismatch | The value does not match the format, for example a time that is not on a 5-minute mark |
Conflicts and state errors
| Status | error | Meaning | What to do |
|---|---|---|---|
| 409 | already_exists | A monitor already exists for this account | Update it instead |
| 409 | concurrent_modification | Another change to the same kind of resource is in progress | Retry after about a second |
| 409 | addon_disconnected | The change needs your NinjaTrader add-on connected (for example to check that an account is yours) | Connect the add-on and retry |
| 409 | addon_version_unsupported | The change needs a newer add-on | Update the add-on |
| 404 | account_not_found | The account is not on your connection. On connection settings, fields lists where the unknown ones are | Check the account name |
| 409 | account_identity_unresolved | The Tradovate account could not be matched to your linked login | Check the name, or re-link Tradovate |
| 409 | tradovate_not_linked | Your Tradovate login is not linked | Link Tradovate in the web app |
| 409 | monitor_locked | Monitor Lock is on and the account reached a limit today | Wait for the 5:00 to 6:00 PM ET window, or turn Monitor Lock off |
| 409 | monitor_stopped_use_restart | The monitor is stopped and active: true cannot resume it | Use the restart endpoint |
| 409 | monitor_not_stopped | Restart was called on a monitor that is not stopped | Nothing to do |
| 409 | would_retrip | Restarting now would stop the monitor again right away | Adjust the limit first |
| 409 | tandem_dependency | The account is a follower in a Tandem copier | Turn off Tandem or remove that copier first |
| 409 | tandem_requires_monitor | Tandem needs a monitor on every follower account | Create the monitors first |
| 409 | copier_cycle | The copier would create a copy loop. Inactive copiers count | Change the leader or followers |
| 409 | duplicate_copier | A copier from this leader to this follower already covers these instruments, even if that copier is inactive | Edit the existing copier |
| 409 | duplicate_follower | A follower appears more than once | Remove the duplicate |
| 409 | follower_conflict | The follower is already used by another copier in a conflicting way | Change the follower |
| 409 | autosync_conflict | Two Auto-Sync copiers would manage the same follower and instrument | Turn off Auto-Sync on one, or split the instruments |
| 409 | group_name_conflict | The name is already used by another group or by an account | Choose another name |
| 409 | group_limit_reached | You have the maximum number of account groups | Delete a group first |
| 409 | template_name_conflict | An ATM template with this name exists | Choose another name |
| 409 | limit_reached | You reached the maximum allowed for this resource | Remove or pause one first |
| 409 | field_locked | This setting is managed by another feature on this account | Change it where that feature is configured |
| 409 | switches_locked | blockSignals or closingOnly was changed on a monitor whose switches are locked (switchesLocked: true) | Send switchesLocked: false in the same request, or unlock first |
| 412 | precondition_failed | If-Match did not strongly match: the resource changed, or you supplied a weak tag | Read it again and use the current strong ETag in meta.etag |
When the outcome is uncertain
| Status | error | Meaning | What to do |
|---|---|---|---|
| 503 | storage_unavailable | The change could not be saved and nothing was applied | Retry shortly |
| 503 | outcome_unknown | The change may or may not have been applied | Read the resource before retrying |