Skip to content

Case Status Tracking

This guide covers the three main use cases and approaches for tracking case status through the Amili API. Depending on your use case, you can query individual cases on demand, retrieve paginated lists of open cases, or periodically get closed cases for reconciliation.

All API requests require a valid authentication token in the X-API-Key header. For details about the authentication process and token management, see the Authentication documentation.

In this guide, we will use the AuthTokenProvider class (documented in the authentication guide) to handle token management.

Table of Contents


Get Current Case Status

When you need the current status of a specific case — for example during a conversation with the debtor, or when reviewing a case in your case management system — query the API directly rather than relying on cached or periodically fetched data.

Avoid relying on periodic polling for current status

Fetching case data on a schedule and storing it locally introduces staleness. Case status can change at any time (payments, state transitions, closures), and acting on outdated information risks incorrect decisions, actions, or communications — particularly towards debtors.

The API also supports paginated queries with filtering and sorting, making it well suited for integrating directly into your case management UI. For example, you can query for all open cases belonging to a specific creditor and display them in a paginated table — always reflecting the current state without the need for a local copy.

Single Case Lookup

Retrieve status information for a specific case using the Case endpoint:

typescript
const token = await auth.getValidToken()
const caseId = '6867da7788b9226bb78d716c'

const projection = encodeURIComponent(
  JSON.stringify({
    _id: 1,
    state: 1,
    status: 1,
    closed: 1,
    'debt.invoice_number': 1,
    total_remaining_capital_amount: 1,
  })
)

const response = await axios.get(
  `https://api-sandbox.amili.se/cases/${caseId}?projection=${projection}`,
  {
    headers: {
      'X-API-Key': token,
    },
  }
)
python
import json

token = auth.get_valid_token()
case_id = '6867da7788b9226bb78d716c'

projection = json.dumps({
    '_id': 1,
    'state': 1,
    'status': 1,
    'closed': 1,
    'debt.invoice_number': 1,
    'total_remaining_capital_amount': 1,
})

response = requests.get(
    f'https://api-sandbox.amili.se/cases/{case_id}',
    params={'projection': projection},
    headers={'X-API-Key': token}
)
response.raise_for_status()
result = response.json()

Example response:

json
{
  "_id": "6867da7788b9226bb78d716c",
  "debt": {
    "invoice_number": "INV-2025-003"
  },
  "state": "debt_collection",
  "status": "debt_collection_active",
  "total_remaining_capital_amount": 2050.0
}

Track Open Cases

For periodic reporting and portfolio oversight, we recommend a scheduled batch query of all open cases. This gives you a full picture of outstanding debts, current states, and remaining capital across your portfolio at a specific point in time.

typescript
const token = await auth.getValidToken()

const where = encodeURIComponent(JSON.stringify({ closed: { $exists: false } }))
const projection = encodeURIComponent(
  JSON.stringify({
    _id: 1,
    state: 1,
    status: 1,
    'debt.invoice_number': 1,
    total_remaining_capital_amount: 1,
  })
)

const response = await axios.get(
  `https://api-sandbox.amili.se/cases?where=${where}&projection=${projection}&sort=-_created&max_results=50`,
  {
    headers: {
      'X-API-Key': token,
    },
  }
)
python
import json

token = auth.get_valid_token()

where = json.dumps({'closed': {'$exists': False}})
projection = json.dumps({
    '_id': 1,
    'state': 1,
    'status': 1,
    'debt.invoice_number': 1,
    'total_remaining_capital_amount': 1,
})

response = requests.get(
    'https://api-sandbox.amili.se/cases',
    params={
        'where': where,
        'projection': projection,
        'sort': '-_created',
        'max_results': 50,
    },
    headers={'X-API-Key': token}
)
response.raise_for_status()
result = response.json()

Example response:

json
{
  "_items": [
    {
      "_id": "6867da7788b9226bb78d716c",
      "debt": { "invoice_number": "INV-2025-003" },
      "state": "debt_collection",
      "status": "debt_collection_active",
      "total_remaining_capital_amount": 2050.0
    },
    {
      "_id": "68a1bc3388b9226bb78d8a2f",
      "debt": { "invoice_number": "INV-2025-010" },
      "state": "reminder",
      "status": "reminder_sent",
      "total_remaining_capital_amount": 1200.0
    }
  ],
  "_meta": {
    "page": 1,
    "max_results": 50,
    "total": 87
  }
}

Case States

The state field indicates the current stage of an open case:

StateDescription
reminderReminder sent, awaiting payment
debt_collectionIn active debt collection
enforcementAt the enforcement authority (Kronofogden)
debt_surveillanceLong-term debt monitoring
amortizationPayment plan active
disputeUnder dispute
estateEstate administration
bankruptcy_estateDebtor declared bankrupt, estate under administration

Track Closed Cases

For reconciliation and internal reporting, we recommend a periodic batch query of recently closed cases. Cases can close for many different reasons — some result in payouts, while others represent losses that should be written off internally.

Tracking payouts for paid cases

Cases closed with a fully_paid* reason will result in a financial settlement. See the Finance & Payout Management guide for our recommendations on how to track and settle these payouts.

Use the closed.close_date field with the $gt operator to incrementally fetch cases closed since your last query. Store the last fetched date for future queries to avoid duplicate or missed data.

typescript
const token = await auth.getValidToken()

const where = encodeURIComponent(
  JSON.stringify({
    'closed.close_date': { $gt: 'Mon, 13 Jan 2026 00:00:00 GMT' },
  })
)
const projection = encodeURIComponent(
  JSON.stringify({
    _id: 1,
    closed: 1,
    'debt.invoice_number': 1,
    total_remaining_capital_amount: 1,
  })
)

const response = await axios.get(
  `https://api-sandbox.amili.se/cases?where=${where}&projection=${projection}&sort=-closed.close_date&max_results=50`,
  {
    headers: {
      'X-API-Key': token,
    },
  }
)
python
import json

token = auth.get_valid_token()

where = json.dumps({
    'closed.close_date': {'$gt': 'Mon, 13 Jan 2026 00:00:00 GMT'},
})
projection = json.dumps({
    '_id': 1,
    'closed': 1,
    'debt.invoice_number': 1,
    'total_remaining_capital_amount': 1,
})

response = requests.get(
    'https://api-sandbox.amili.se/cases',
    params={
        'where': where,
        'projection': projection,
        'sort': '-closed.close_date',
        'max_results': 50,
    },
    headers={'X-API-Key': token}
)
response.raise_for_status()
result = response.json()

Example response:

json
{
  "_items": [
    {
      "_id": "507f1f77bcf86cd799439011",
      "debt": { "invoice_number": "INV-2025-020" },
      "closed": {
        "close_date": "Wed, 03 Sep 2025 11:18:59 GMT",
        "reason": "fully_paid"
      },
      "total_remaining_capital_amount": 0
    },
    {
      "_id": "507f1f77bcf86cd799439012",
      "debt": { "invoice_number": "INV-2025-019" },
      "closed": {
        "close_date": "Tue, 02 Sep 2025 14:22:15 GMT",
        "reason": "recalled"
      },
      "total_remaining_capital_amount": 1500.5
    },
    {
      "_id": "507f1f77bcf86cd799439013",
      "debt": { "invoice_number": "INV-2025-018" },
      "closed": {
        "close_date": "Mon, 01 Sep 2025 09:45:30 GMT",
        "reason": "bankruptcy"
      },
      "total_remaining_capital_amount": 2500.0
    }
  ],
  "_meta": {
    "page": 1,
    "max_results": 50,
    "total": 142
  }
}

Close Reasons

The closed.reason field indicates why a case was closed. The reasons fall into two categories:

Paid — the debt has been settled and will result in a payout:

ReasonDescription
fully_paidFully paid by debtor
fully_paid_depreciationFully paid with depreciation applied
fully_paid_before_reminderPaid before the reminder stage
fully_paid_before_debt_collectionPaid before the debt collection stage
capital_paid_to_creditorCapital paid directly to creditor

Unpaid — the debt was not recovered; these cases should typically be reported as losses:

ReasonDescription
bankruptcyDebtor declared bankrupt
deceasedDebtor deceased
recalledRecalled by creditor
creditCredited by creditor
cancellationCancelled
disputeClosed due to dispute resolution
written_offWritten off
debt_restructuringClosed due to debt restructuring
resubmit_invoiceClosed for resubmission as a new case
migratedMigrated to another system