Search skmtc…
⌘K
Docs
Sign in
APIs
Generators
Stacks
Projects
Docs
History
Schema
Generate
Filter operations
get
/v1/health
Liveness check
get
/v1/openapi.json
This OpenAPI document
get
/v1/jurisdictions/resolve
Whether a jurisdiction is served, and its notice rules
post
/v1/geo/county
Find the county of a street address, from the US Census geocoder. The address goes in the body, never the URL; the unit is not passed on, and nothing is stored. When the county cannot be found (no match, a match in another state or in more than one county, or the geocoder failing or taking over 5 seconds) the answer is `{ "county": null }`, never an error. At most 60 an hour per organization (429 `rate_limited`)
get
/v1/intake/address
The organization's email intake address, `cases+<token>@<domain>`: email sent to it by a member of the organization whose address is confirmed puts its attachments and its text in the intake inbox. Made on the first call, the same afterwards. Live only: a test key answers 422 `live_only`
post
/v1/intake/address/rotate
Replace the organization's email intake address with a new one. Email sent to the old address is no longer received. A signed-in owner only (an API key answers 403). Live only
get
/v1/integrations
List the organization's stored property-management connections (Buildium, DoorLoop), without their credentials. A signed-in session in live mode only: an API key answers 403
post
/v1/integrations/{system}/connect
Connect Buildium (`credentials: { clientId, clientSecret }`) or DoorLoop (`credentials: { token }`) for the organization. The key is checked with one read-only call to the system, then stored encrypted, replacing any earlier one; it is never returned. An owner's signed-in session in live mode only
delete
/v1/integrations/{system}
Disconnect a property-management system: its stored key is deleted. An owner's signed-in session in live mode only
post
/v1/integrations/{system}/leases
Search the connected system's leases: by tenant name in Buildium, by lease name (which names its unit and tenants) in DoorLoop. At most 20 leases. A signed-in session in live mode only
post
/v1/integrations/{system}/pull
Read one lease from the connected system as suggested answers for a new case: the address, the tenants, the lease dates and rent, the ledger and the system's balance, and its lease PDF when it has one. A part the system no longer has (a tenant, the unit) is left out. Nothing is stored or filed by this. A signed-in session in live mode only
get
/v1/intake/files
List the files waiting in the organization's intake inbox, oldest first: files the customer already has (a lease, a ledger, an email) kept until a case is started. Live only: a test key answers 422 `live_only`
post
/v1/intake/files
Keep a file in the organization's intake inbox until a case is started: a PDF, JPEG or PNG of at most 4 MB, decided by its contents. The inbox holds 50 waiting files (409 `inbox_full`), each for 30 days. Live only: a test key answers 422 `live_only`
post
/v1/extract
Read a lease (PDF, JPEG or PNG, at most 4 MB and, for a PDF, 40 pages, as base64) with an AI service (Claude Haiku 4.5 through OpenRouter) and answer the facts the new-case form takes. For a file the free reading on the device could not read. With `kind: "correspondence"` and `files` (1 to 10 messages with the tenant: PDF, JPEG, PNG, plain text `text/plain`, or a saved email `message/rfc822` (`.eml`, at most 1 MB, turned into its text before it is sent); 8 MB, 40 PDF pages and 200,000 characters of text in all), it drafts what happened for a lease-violation case (`violationDescription`, `violationDate`): a draft for the person to read and correct, never a checked answer. One request counts once against the hourly limit, whatever the number of files. With `kind: "ledger"` and one `file` (a tenant ledger PDF, at most 4 MB and 40 pages), it answers the ledger's rows (`rows`, each `{ date, type: "charge" | "payment", amountCents, memo }`, at most 500, in the order printed) a balance brought forward from before them (`openingBalanceCents`, null when none) and the ending balance the ledger states (`endingBalanceCents`, null when it states none), for the caller to check: the balance brought forward and the rows should add up to the ending balance, and the website fills in nothing when they do not. A row dated after today is left out. The files are sent to OpenRouter only for this one reading, under fixed names (the `name` you send is never passed on), on endpoints that keep no data; nothing is stored and nothing of the files or the answer is logged. Every answer is a suggestion for a person to check: a fact the reading is unsure of is left out, never guessed. When the service refuses, fails or takes over 30 seconds, the answer is empty (`{ "suggestions": {}, "confidence": {} }`, or for a ledger `{ "rows": [], "openingBalanceCents": null, "endingBalanceCents": null }`), never an error. For now only the signed-in app and test keys can use it: a live API key answers 503 `extract_unavailable`. At most 20 an hour per organization (429 `rate_limited`); 503 `extract_unavailable` when the server has no AI service set
get
/v1/intake/files/{id}
Download a waiting file of the intake inbox. A file moved onto a case is downloaded as that case's document instead (404 here). Live only
delete
/v1/intake/files/{id}
Delete a waiting file of the intake inbox. Live only
get
/v1/cases
List the cases of the key's organization and mode, optionally only those one person opened (`openedBy`)
post
/v1/cases
Create a draft case. For a live case the property must be in a US state or DC (422 `unsupported_state`) and the case is an attorney-direct case. `service: "full"` asks for the full-service path (we act as your agent, no attorney reviews the case); the case gets it only where that path is open for the property, and otherwise answers 409 `service_unavailable` without creating a different service: check availability first
get
/v1/cases/{id}
Get a case
patch
/v1/cases/{id}
Change the facts of a draft case, or (`paymentMethodId`, in any state) the saved card a full-service case is charged to. 409 `not_agent_filed` for a card on a case that is not full-service; 422 `payment_method_not_found` for a card that is not one of the organization's usable cards in this mode
get
/v1/cases/{id}/managed-facts
Which facts one proposed act of a managed case is missing. The facts are the customer's declaration, and an empty list is not permission to perform the act
post
/v1/cases/{id}/documents
Upload evidence for a draft case: a PDF, JPEG or PNG, decided by the file's contents (415 `unsupported_media_type` otherwise, for a live case). A `correspondence` document may also be plain UTF-8 text, such as the body of a forwarded email, stored as `text/plain`. For a live case, `purpose: "other"` files can also be added after submission, until the case is finished
post
/v1/cases/{id}/documents/from-intake
Move a waiting file of the intake inbox onto a live case as a document of `purpose`, as an upload of the same file would be (the same checks apply: 409 `invalid_state` once a case is submitted, except `purpose: "other"`). The text of a forwarded email (`text/plain`) moves only as `correspondence`; any other purpose answers 415 `unsupported_media_type`. The file leaves the inbox. Moving a file already moved onto this case answers 200 with the same document; a test case answers 422 `live_only`
get
/v1/cases/{id}/documents/{docId}
Download a document of the case
post
/v1/cases/{id}/validate
Run the submission gates on a draft
post
/v1/cases/{id}/submit
Submit a draft that passes every gate. A live case moves to `submitted`, its platform fee becomes a due charge, and we engage a licensed attorney in the property's state; nothing is served or filed until that attorney has reviewed it. A test case enters review by the built-in test reviewer
get
/v1/cases/{id}/authorization
The authorization text of an agent-filed case, and whether it is signed and still current. 409 `not_agent_filed` for any other case
post
/v1/cases/{id}/authorization
Sign the authorization of an agent-filed case, for the facts as they are now. Only while the case is a draft (409 `invalid_state`); 409 `not_agent_filed` for any other case. Signing again replaces the earlier signature
get
/v1/cases/{id}/signatures/complaint
The complaint documents the owner must sign on an agent-filed case, and whether they are signed. 409 `not_required` when the county has us sign the complaint, or there is none yet; 409 `not_agent_filed` for any other case
post
/v1/cases/{id}/signatures/complaint
Sign the complaint of an agent-filed case, where the county requires the owner to. Only while the case waits for the signature in `filing_approved`; 409 `not_required` otherwise, and 409 `not_agent_filed` for any other case. The filing is queued once. Where the filing is an affidavit sworn by electronic verification (`sworn` on the GET), only the named affiant signs, `accept: true` is the oath, `signerName` must be the affiant's name as printed (case and spacing aside; 422 `affiant_name_mismatch`), and `documentHashes` must be the `sworn.documents` hashes read (409 `documents_changed` when the affidavit changed since, for example on a new day): those documents become the filing
get
/v1/cases/{id}/signatures/complaint/documents/{specId}
Download a sworn affidavit by its spec id. Before the oath (while the case waits for it in `filing_approved`): exactly as it will be filed if your named person swears it now, signed "/s/" with the affiant's name and dated today (the court's day). Once sworn: the affidavit that was sworn, as stored for the filing. 404 for any other document or case; 410 `erased` for an erased case
get
/v1/cases/{id}/tasks
The outward steps of a full-service case, oldest first, each with its status and dates. 409 `not_agent_filed` for any other case
get
/v1/cases/{id}/events
Customer-visible events of the case, oldest first
post
/v1/cases/{id}/report-cure
Report that the tenant has paid or cured. For a live case the report is recorded and passed on to the attorney; the case is not closed automatically
post
/v1/cases/{id}/withdraw
Withdraw the case. A live case with an attorney already engaged goes `on_hold` with a `withdrawal_requested` event instead, and is withdrawn once the attorney has confirmed that all work has stopped
get
/v1/cases/{id}/charges
The charges on the case, oldest first, and whether online payment is available
post
/v1/cases/{id}/charges/{chargeId}/checkout
Open a hosted checkout for one due charge. 409 `payments_unavailable` when online payment is off; 409 `charge_not_due` when the charge is paid, void or refunded; 409 `automatic_charge` for a charge taken from the saved card
post
/v1/cases/{id}/charges/{chargeId}/confirm
Check with the payment provider whether the charge's checkout was paid, and record it if so. Safe to repeat. 409 `payments_unavailable` when online payment is off; 409 `automatic_charge` for a charge taken from the saved card
get
/v1/payment-methods
The organization's saved cards for the automatic charges of full-service cases, in the key's mode: the default first, then newest first. Anyone in the organization can read them
post
/v1/payment-methods/setup
Open the payment provider's page for adding a card. The card number is typed there and never reaches the API. The customer comes back to `returnPath` on the website with `setup_session` in the query (and `default=true` when `default` was asked for); send those to `confirm`. With a test key there is no card page and no real card: the returned URL only carries the setup's id in its `session` parameter; finish the setup with `POST /v1/payment-method/test-setup`, then `confirm` it. Needs the permission to manage payment methods. In live mode, 409 `live_unavailable` until live full-service cases are switched on; 503 `payments_unavailable` when online payment is off
post
/v1/payment-methods/confirm
Add the card of a finished setup to the organization's cards in this mode. It becomes the default with `default: true`, or when the organization has no usable default. Every automatic charge still due is then retried shortly after, in the background. Safe to repeat: a card already added is answered as it is. 409 `setup_incomplete` while the card is not saved yet; 404 for a setup that is unknown, another organization's, or of a card removed since
delete
/v1/payment-methods/{id}
Remove a card: it is detached at the payment provider and never charged again. When it was the default, the newest card left that works becomes the default; with none left, a full-service case with a cost due waits until a card is added. 404 for a card that is not one of the organization's in this mode
patch
/v1/payment-methods/{id}
Name a card (`label`, null to clear it) or make it the default (`default: true`). 422 `payment_method_unusable` for a declined card made the default, and then nothing is changed. 404 for a card that is not one of the organization's in this mode. Each change is in the organization's activity log
get
/v1/charges
Every charge of the organization's cases in this mode, newest first, optionally only one status or the charges created between two days (UTC), with the billing page's totals. Anyone in the organization can read them
get
/v1/charges.csv
The same charges as a CSV file (at most 10,000 rows, newest first), named `charges-YYYY-MM-DD.csv` after the day of the request. Columns: created_at, charge_id, case_id, state, kind, description, amount_usd, status, paid_at, receipt_url. No names, addresses or payment-provider ids
get
/v1/payment-method
The default card for the automatic charges of full-service cases, in the key's mode, or null when there is none. Kept for older clients: `GET /v1/payment-methods` lists every card
post
/v1/payment-method/setup
Open the payment provider's page for saving a card. The card number is typed there and never reaches the API. The customer comes back to `returnPath` on the website with `setup_session` in the query; send that to `confirm`. With a test key there is no card page and no real card: the returned URL only carries the setup's id in its `session` parameter; finish the setup with `POST /v1/payment-method/test-setup`, then `confirm` it. In live mode, 409 `live_unavailable` until live full-service cases are switched on (the full service is offered only in test mode for now). 503 `payments_unavailable` when online payment is off
post
/v1/payment-method/confirm
Add the card of a finished setup to the organization's cards in this mode, as the default card (kept for older clients: `POST /v1/payment-methods/confirm` chooses). Every automatic charge still due is then retried on it shortly after, in the background; a case on hold for a declined card continues once its costs are paid. Safe to repeat. 409 `setup_incomplete` while the card is not saved yet; in live mode, 409 `live_unavailable` until live full-service cases are switched on
post
/v1/payment-method/test-setup
Test mode only (409 `sandbox_only` otherwise): finish a test setup with one of the two test cards, `success` (Visa ending 4242) or `decline` (ending 0002, which declines every charge). `sessionId` is the `session` parameter of the URL that `POST /v1/payment-method/setup` returned for the test key
get
/v1/cases/{id}/notes
The messages on the case: the customer's own and ours, oldest first
post
/v1/cases/{id}/notes
Send us a message about a live case. 409 `attorney_direct_only` for a test case. At most 20 every 10 minutes per organization (429 `rate_limited`)
post
/v1/cases/{id}/advance
Test keys only: move a test case on by one step. Runs the step the case is waiting for now (the test reviewer's review, a service or filing update, or the end of the notice period on the case's own test clock), or records the next court outcome as the test reviewer. A live case (nothing about a real case is ever advanced automatically), or a case outside the fictional test state, gets 409 `sandbox_only`; a draft, a case on hold or a finished case gets 409 `nothing_to_advance`, as does a step whose last try failed, until its automatic retry (`error.details.retryAt`). While the step is already being taken, the case is returned as it is. At most 60 a minute per organization (429 `rate_limited`)
get
/v1/webhook-endpoints
List the organization's webhook endpoints in the credential's mode. The signing secret is never shown again
post
/v1/webhook-endpoints
Register a webhook endpoint
get
/v1/api-keys
List the organization's API keys in the credential's mode, newest first, revoked ones included. The secret is never shown again
post
/v1/api-keys
Create an API key in the credential's mode, optionally with a name. With `replaceSameName`, the active keys of the mode with that exact name are revoked first, so an app that connects again keeps one key. A live key can be created only by an owner of the organization, signed in with a session and `X-Evictions-Mode: live` (403 `forbidden` otherwise, also for a live API key); at most 10 active keys per mode, counted after any replaced keys (409 `key_limit`, and then nothing is revoked)
delete
/v1/api-keys/{id}
Revoke an API key of the organization and the credential's mode. A key cannot revoke itself (409 `cannot_revoke_current_key`)
delete
/v1/webhook-endpoints/{id}
Delete a webhook endpoint. Deliveries still waiting to be retried for it are dropped
get
/v1/organization
The caller's organization and its members
patch
/v1/organization
Change the organization's profile: its name, kind and contact details (`organization.manage`, an owner by default) and the billing contact (`billing.manage`); a request with both needs both. Only the fields given change; null clears one. An API key gets 403
delete
/v1/organization/members/{userId}
Remove a person from the organization. Needs `people.manage`; an owner is removed by an owner only, and never the last one. Their sessions acting for the organization are signed out, their other organizations stay, and they are emailed. Their cases, messages and signatures stay with the organization
patch
/v1/organization/members/{userId}
Change a member's role (`owner`, `member`, `viewer`), or give them a `custom` list of permissions. Needs `people.manage`; only an owner makes, changes or removes an owner, and nobody gives a permission they do not hold. The last owner cannot be demoted. The person is emailed unless they changed their own role
get
/v1/organization/activity
The organization's activity log: invitations, role changes, removals and profile changes, newest first. A signed-in person who manages people; an API key or anyone else gets 403
get
/v1/organization/invitations
The organization's invitations. A signed-in person who manages people; an API key or anyone else gets 403
post
/v1/organization/invitations
Invite a person by email, as an owner (owners only), member or viewer. A pending invitation to the same address is replaced. The link lasts seven days
post
/v1/organization/invitations/{id}/resend
Email a pending invitation again with a new link. The old link stops working
delete
/v1/organization/invitations/{id}
Revoke a pending invitation. Its link stops working
get
/v1/attorney/queue
Cases awaiting the attorney's review, and assigned cases that need attention
get
/v1/attorney/cases/{id}
A case with its documents, evidence, gate results, filings, service attempts and full audit trail; the access is audited
get
/v1/attorney/cases/{id}/documents/{docId}
Download a document; the access is audited
get
/v1/attorney/counsel-assignments
The calling attorney's limited counsel engagements: the one act each covers, its terms and the documents it grants
get
/v1/attorney/counsel-assignments/{id}/documents/{docId}
Download a document an accepted engagement grants; the access is audited
post
/v1/attorney/cases/{id}/reviews
Approve, reject or request changes, naming the document hashes reviewed
post
/v1/attorney/cases/{id}/outcomes
Record a court outcome
post
/v1/auth/signup
Create an account: an unverified customer organization, its owner and a session. No credential; the website calls this from its servers
post
/v1/auth/login
Sign in with email and password. A wrong email and a wrong password get the identical `invalid_credentials` answer
post
/v1/auth/google
Sign in with Google: the website trades the code Google gave it. Signs in to the account linked to that Google account, else links the account with the same email when it has no password (one with a password answers 409), else creates one (201) with no password. With `invitationToken` it also accepts that invitation: the Google account's email must be the invited address, a new account gets no organization of its own, and the session acts for the inviting organization. No credential; the website calls this from its servers
get
/v1/invitations/{token}
An invitation, from the link in its email: the organization, the role and the invited address, masked. No credential; the token is the credential
post
/v1/invitations/{token}/accept
Accept an invitation. Signed out, with a name and a password: makes the account for the invited address, confirmed, and answers 201 with a session for the organization. Signed in as the invited address, with no body: joins the organization and moves the session there (200). An address that already has an account must sign in to accept; its password is never set here
post
/v1/auth/logout
Revoke the session in use
post
/v1/auth/password-reset/request
Ask for a password reset link by email. No credential. The answer is the same whether or not the address has an account
post
/v1/auth/password-reset/confirm
Set a new password with the token from a reset link. No credential. The token works once; every session of the user is revoked
post
/v1/auth/email-confirm/request
Send a new "Confirm your email" link to the signed-in user's own address. The answer is always 202
post
/v1/auth/email-confirm/confirm
Confirm the address with the token from the emailed link. No credential. The token works once. Confirming is never required for anything
get
/v1/me
The signed-in person, the organization this session acts for, their role and permissions in it, and every organization they belong to
patch
/v1/me
Change the signed-in person's name
post
/v1/me/organization
Act for another of the person's organizations. The session moves there, and the next sign-in starts there
post
/v1/me/organizations
Start another organization, unverified, with the person as its owner; the session moves to it. Customer accounts only
post
/v1/me/organizations/{id}/leave
Leave an organization. The person's other sessions acting for it are signed out; this one moves to their oldest remaining organization, or to none
patch
/v1/me/organizations/{id}
Choose which of the organization's case emails the person gets: `all`, `mine` (cases they opened) or `none`
post
/v1/me/password
Change the person's password, with the current one. Every other session of the person is signed out (this one stays), and their pending email change and password reset links stop working
post
/v1/me/email
Ask to change the person's email, with the current password. A link goes to the new address and the address changes only when it is opened; the old address is told
post
/v1/me/email/confirm
Change the email with the token from the link sent to the new address. No credential. The token works once
post
/v1/me/sessions/revoke-others
Sign out every other session of the person, keeping this one
get
/v1/public/pricing
The prices in force: the platform fee for each starting step and the flat attorney fees of the published states. No credential; cached for a minute
post
/v1/public/leads
Send a website request: access, a partner-attorney application, or a message. No credential; browser calls are allowed from the website origin only
Copy
Copy Markdown
Copy Markdown
Copying…
Copied
Copy failed
Generate code
Liveness check
get
/v1/health
Request
Base URL:
https://api.evictionsapi.com
URL:
https://api.evictionsapi.com/v1/health
Auth:
none required
Response
The service is up.
object
required
ok
boolean
Changes
No recorded changes to this operation across all 1 revision of this API.