Create and Respond to a Case with the API
File an arbitration case with the contract, your argument, evidence, and the respondent — then take turns responding until the case is decided. Signing and payment happen by email, and both parties view the answer online. For the consent-case quickstart, see the Quickstart.
This is a preview of the intended API. If you want access please contact us — casemanager@decisionlayer.ai
How it works
-
1
Create the case —
POST /api/v1/caseswith the contract, your opening argument, evidence, and who the respondent is. -
2
Sign and pay by email — the system emails you a link to sign the case, then a link to pay the filing fee. No API calls; the case is filed and the respondent notified once payment completes.
-
3
Respond in turns — whoever
current_turnnames callsPOST /api/v1/cases/{id}/responseswith their argument and evidence. Each party uses their own API key; out-of-turn submissions get a 409. After each submission you get an email to sign it, and the turn passes. -
4
Track progress — poll
GET /api/v1/cases/{id}forstatusandcurrent_turn. When the rounds are complete the case is submitted for decision. -
5
View the answer online — when the case is decided, both claimant and respondent open the case's
view_urlto see the decision on the web. There is no decision endpoint.
Authenticate every request with a bearer token:
Authorization: Bearer dvarb_your_key_here.
Claimant and respondent each use their own key; parties without a
key simply follow the emailed links instead.
create_real_case.py
"""DecisionLayer API: file an arbitration case and respond in turns.
The flow this script walks through:
1. Create the case with the contract, your opening argument, evidence, and
the respondent's identity (one API call).
2. Sign and pay -- these happen BY EMAIL, not through the API. Watch your
inbox after step 1.
3. Poll the case for whose turn it is; submit a response when it's yours.
After each submission you get an email to sign it.
4. When the case is decided, both parties view the answer ONLINE at the
case's view_url (there is no decision endpoint).
Endpoints other than listing are Planned: this script shows the intended
contract and will work once they ship.
The only thing you need to change is API_KEY below. Create a key at
https://www.decisionlayer.ai/settings/api-keys
Then run:
pip install requests
python create_real_case.py
"""
import time
import requests
# 1. Paste your API key here (from /settings/api-keys).
API_KEY = "PASTE_YOUR_KEY_HERE"
# 2. Base URL of the DecisionLayer API. Use http://localhost:8000 locally.
BASE_URL = "https://www.decisionlayer.ai"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# Set to "claimant" if you filed the case, "respondent" if you were named.
MY_ROLE = "claimant"
def create_case() -> dict:
"""File the case: contract + argument + evidence + respondent."""
# Create small sample attachments so the demo is self-contained.
with open("sample_contract.txt", "w") as handle:
handle.write("Sample contract for the DecisionLayer demo.\n")
with open("sample_evidence.txt", "w") as handle:
handle.write("Sample evidence: deposit receipt.\n")
data = {
"question_for_arbitration": "Respondent kept a $3,500 deposit.",
"argument": (
"The contract required return of the deposit within 30 days. "
"It has been 90 days and the deposit has not been returned."
),
"financial_demand_usd": "3500.00",
"respondent_first_name": "Jordan",
"respondent_last_name": "Chen",
"respondent_email": "jordan.chen@example.com",
}
with (
open("sample_contract.txt", "rb") as contract,
open("sample_evidence.txt", "rb") as evidence,
):
files = [
("contract_files", ("sample_contract.txt", contract, "text/plain")),
("evidence", ("sample_evidence.txt", evidence, "text/plain")),
]
response = requests.post(
f"{BASE_URL}/api/v1/cases",
headers=HEADERS,
data=data,
files=files,
timeout=60,
)
if response.status_code != 201:
print(f"Create failed ({response.status_code}):")
print(response.json())
raise SystemExit(1)
case = response.json()["case"]
print(f"Created case: {case['id']} (status: {case['status']})")
print("Check your email to SIGN the case. After signing, a second email")
print("will ask you to PAY the filing fee. The case is filed and the")
print("respondent is notified once payment completes.")
return case
def get_case(case_id: str) -> dict:
"""Fetch the case: status, current_turn, and view_url."""
response = requests.get(
f"{BASE_URL}/api/v1/cases/{case_id}", headers=HEADERS, timeout=60
)
response.raise_for_status()
return response.json()
def submit_response(case_id: str, argument: str) -> None:
"""Submit this round's argument. Only works when it's your turn (409 otherwise)."""
response = requests.post(
f"{BASE_URL}/api/v1/cases/{case_id}/responses",
headers=HEADERS,
data={"argument": argument},
timeout=60,
)
if response.status_code == 409:
print("Not your turn yet:")
print(response.json()["error"]["details"])
return
response.raise_for_status()
print("Response submitted. Check your email to SIGN it; the turn passes")
print("to the other party once you sign.")
def main() -> None:
case = create_case()
case_id = case["id"]
# Poll for the case state. In practice you'd wait for email
# notifications; polling here just demonstrates the read surface.
for _ in range(5):
case = get_case(case_id)
status, turn = case["status"], case["current_turn"]
print(f"Status: {status}, turn: {turn}")
if status == "decided":
print(f"The decision is ready. View it online: {case['view_url']}")
return
if status in ("withdrawn", "closed"):
print("The case ended without a decision.")
return
if status == "awaiting_response" and turn == MY_ROLE:
submit_response(
case_id,
"Section 4.2 does not apply; the termination was mutual.",
)
time.sleep(5)
print("Still in progress. Re-run later, or watch your email for updates.")
print(f"You can always view the case online: {case['view_url']}")
if __name__ == "__main__":
main()
Understanding errors
Every error returns a consistent JSON shape with a list of
actionable details.
The most common in this flow is a 409 when it is not your turn:
{
"error": {
"status": 409,
"message": "It is not your turn to respond.",
"details": [
"This case is awaiting a submission from the respondent.",
"Poll GET /api/v1/cases/{case_id} and submit when current_turn matches your role."
]
}
}