REST API

Errors

HTTP status codes, machine-readable error codes, and the extra fields that accompany errors.

When a request fails, the response body has this shape:

{
  "ok": false,
  "error": "similar",
  "message": "Benzer adlı firma var — mevcut kaydı seçin ya da confirm_new=1 ile yeni açın.",
  "similar": [ { "id": 7, "name": "Alize Paketleme San. ve Tic. A.Ş.", "…": "…" } ]
}
  • error is a stable, machine-readable code — branch on it in your code.
  • message is a Turkish description you can show to users; its wording may change, so don't parse it.
  • Some errors carry extra fields: similar, customer, gate_problems, module, state, otp.

Error codes

Code HTTP Meaning
unauthorized 401 Missing, invalid, expired or revoked token.
credentials 401 Wrong username or password.
otp_required 401 Two-factor code required (otp).
otp_invalid 401 Wrong or expired two-factor code.
forbidden 403 You may not see / edit this record.
insufficient_scope 403 The OAuth token lacks crm.write.
module 403 The module is off in the licence or for the user.
license 403 The licence expired — admins only.
ip 403 Access from this network is not allowed (IP restriction).
not_found 404 Record not found.
invalid 400 Missing or invalid field (message explains).
send 400 The e-mail could not be sent (no mailbox, bad recipient…).
exists 409 A company with this name exists (returned in customer).
similar 409 Similar names exist (similar); send confirm_new: true to create anyway.
gate 409 Stage gate not met (gate_problems).
locked 429 Too many failed sign-ins — wait 60 s.
rate_limited 429 Per-minute request limit exceeded (Retry-After).
limit 429 Hourly question limit per user (40) reached.

HTTP status codes

Code Meaning
200 Success.
201 Created (OAuth client registration, SCIM user creation).
204 Success with no content (SCIM user deactivation).
400 Missing or invalid field.
401 Authentication failed — refresh the token or sign in again.
403 Not permitted — role, module, scope, license, or IP.
404 The record doesn't exist or is outside what you're allowed to see.
405 Method not supported (for example, GET on the MCP endpoint).
409 Business rule conflict — duplicate company, stage gate.
429 Rate limit — wait for the number of seconds in Retry-After.
500 Server error. If it keeps happening, send the request and the time to info@solk.app.

Example: duplicate company

r = s.post(f"{BASE}/api/v1/customers", json={"name": "Alize Ambalaj"})
j = r.json()
if r.status_code == 409 and j["error"] == "exists":
    company = j["customer"]                     # already exists — use it
elif r.status_code == 409 and j["error"] == "similar":
    candidates = j["similar"]                   # let the user pick, or:
    j = s.post(f"{BASE}/api/v1/customers", json={"name": "Alize Ambalaj", "confirm_new": True}).json()

Example: stage gate

r = s.post(f"{BASE}/api/v1/opportunities/{oid}/stage", json={"stage": "Viable"})
if r.status_code == 409 and r.json()["error"] == "gate":
    for problem in r.json()["gate_problems"]:
        print("Missing:", problem)