Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.judit.io/llms.txt

Use this file to discover all available pages before exploring further.

🤖 This is the single error reference for the Judit API: HTTP 2xx/4xx/5xx codes, internal exceptions (name), application_error returned in payload (even when HTTP is 200), and practical troubleshooting.

Anatomy of an error

The Judit API distinguishes two error types:

Transport errors (HTTP 4xx/5xx)

The request failed on basic validation, authentication, authorization or server side. The payload follows { error: { name, message, data } }.

Application errors (response_type: application_error)

HTTP is 200, but the query did not return the expected object. It can be “lawsuit not found”, “homonym”, secrecy, etc. Comes inside responses[].response_type = application_error.

HTTP Status Codes

The API uses standard HTTP conventions.

Success (2xx)

HTTPMeaningWhen it happens
200OKRequest processed and data returned successfully.
201CreatedResource (e.g. new tracker, new request) created successfully.
202AcceptedRequest accepted and queued for asynchronous processing.

Client Errors (4xx)

HTTPTypical error.messageWhen it happensHow to resolve
400BAD_REQUESTMalformed payload, missing required fields, invalid enum.Check error.data — lists failed validations. See Lawsuit Schema.
401UNAUTHORIZEDapi-key missing or invalid.Check the api-key header (no space, no Bearer). See Authentication.
403FORBIDDENapi-key is valid but lacks permission (e.g. unbought feature, secrecy without credential).Verify the feature is enabled in your plan and that there’s a court credential in the Vault.
404NOT_FOUNDResource doesn’t exist — invalid request_id/tracking_id, CNJ not in datalake.Confirm the ID. For new CNJs, fire a previous async query via POST /requests.
409CONFLICTTracking already exists for the same CNJ + key; attempt to create duplicated resource.List existing trackers via GET /tracking. Update the existing one instead of recreating.
422UNPROCESSABLE_ENTITYValid structure but semantically invalid (e.g. search_type incompatible with response_type).See the table at Search Types.
429TOO_MANY_REQUESTSPlan rate limit exceeded.Implement exponential backoff. Check X-RateLimit-* headers in response.

Server Errors (5xx)

HTTPTypical error.messageWhen it happensHow to resolve
500INTERNAL_SERVER_ERRORUnexpected Judit-side failure.Retry with backoff. If it persists, open a ticket at support@judit.io referencing the request_id.
502 / 504BAD_GATEWAY / GATEWAY_TIMEOUTOriginating court down or timeout. Common in synchronous queries.Retry — if it persists, async flow via POST /requests is more resilient.
503SERVICE_UNAVAILABLEMaintenance.Wait a few minutes. Watch status.judit.io (if enabled).

HTTP error payload structure

Regardless of status (400 or 500), the response body always follows this contract:
{
    "error": {
        "name": "HttpBadRequestError",
        "message": "BAD_REQUEST",
        "data": [
            {
                "field": "search.search_key",
                "rule": "required",
                "message": "search_key is required"
            }
        ]
    }
}
FieldDescription
error.nameException code (e.g. HttpBadRequestError, HttpNotFoundError, HttpUnauthorizedError, USER_NOT_FOUND). Use in your switch/case for automation.
error.messageFriendly category (BAD_REQUEST, UNAUTHORIZED, etc.).
error.dataDetails — array of validations or string with specific message. Useful for displaying form validations to the end user.

Internal codes (error.name)

Use these values for programmatic automation:

Authentication and permissions

Code (name)HTTPCommon cause
USER_NOT_FOUND401API key not sent or revoked.
INSUFFICIENT_PERMISSIONS403Attempt to use a module blocked in your plan.
HttpUnauthorizedError401Generic — invalid key.

Validation and processing

Code (name)HTTPCommon cause
HttpBadRequestError400Malformed JSON or missing fields.
RESOURCE_NOT_FOUND404CNJ not yet captured.
REQUEST_NOT_FOUND404Queried request_id does not exist.
PROCESSING_ERROR422Bot failed to read court data.

Application errors (application_error)

When you receive response_type: application_error instead of the expected payload, the query was successfully processed, but the result is a logical exception.
response_data.codeMeaningWhen it happensHow to resolve
LAWSUIT_NOT_FOUNDLawsuit not found.Non-existent CNJ or inaccessible.Verify the number and tribunal. May be under secrecy — add customer_key (Vault).
ENTITY_NOT_FOUNDPerson/company not found.CPF/CNPJ doesn’t appear in datalake or court.Try on_demand: true to force court fetch.
WARRANT_NOT_FOUNDWarrant not found in BNMP.No warrants for the given document.Try name or rji search if applicable.
EXECUTION_NOT_FOUNDPenal execution not found.No records for the document.Check the originating court (Penal Execution Justice).
INVALID_CREDENTIALVault credential invalid or expired.Court login/token expired.Update the credential at Vault.
CRAWLER_ERRORCourt collection failed.Court down, captcha failure, layout change.Retry. If it persists, automatic fallback flow kicks in.
RATE_LIMIT_TRIBUNALTribunal-imposed limit.Court blocked further collection.Judit retries automatically next cycle. Use a higher cache_ttl_in_days.
SECRECY_RESTRICTEDSecret lawsuit without associated credential.secrecy_level > 0 and api-key has no court credential.Register a credential at Vault and reference via customer_key.
HOMONYM_AMBIGUOUSName search returned homonyms.Common name without extra criteria.Refine via CPF/CNPJ or apply filters (tribunals, state).

application_error example

{
    "request_id": "87d9f7bf-0071-41ee-a721-e6e1b4082bc9",
    "responses": [
        {
            "response_id": "b6c1a4f0-1234-5678-9abc-def012345678",
            "response_type": "application_error",
            "response_data": {
                "code": "LAWSUIT_NOT_FOUND",
                "message": "Lawsuit 0000000-00.0000.0.00.0000 not found in datalake or court."
            }
        }
    ]
}

Centralized handler (ready-to-use code)

Create a single interceptor to log and handle Judit API errors.
import requests, os

def handle_judit_error(response: requests.Response) -> None:
    """Decode and handle Judit API errors."""
    if response.status_code < 400:
        return
    try:
        payload = response.json()
        error_block = payload.get('error', {})
        error_name = error_block.get('name', 'UNKNOWN_ERROR')
        error_details = error_block.get('data', [])
        print(f"❌ HTTP {response.status_code}: {error_name}")
        if error_details:
            print("Details:")
            for detail in error_details:
                print(f"  - {detail}")
        if error_name == 'USER_NOT_FOUND':
            raise PermissionError("Invalid API key. Check JUDIT_API_KEY.")
        if response.status_code == 429:
            print("⚠️ Rate limit exceeded. Trigger backoff.")
    except ValueError:
        print(f"Critical error {response.status_code}: response is not valid JSON.")
        print(response.text)

Handling patterns

Implement retry with jitter:
import time, random
for attempt in range(5):
    resp = requests.post(url, headers=h, json=body)
    if resp.status_code < 500 and resp.status_code != 429:
        break
    sleep = (2 ** attempt) + random.random()
    time.sleep(sleep)
The Retry-After header (when present) must be respected.
Webhooks redeliver on failure. Always check callback_id before processing — store it in a table (id, received_at). If already present, ignore.
Treat application_error as a valid query result (the integration is fine), while HTTP 4xx indicates that the call is wrong. Log them separately in monitoring.
When the lawsuit is secret and the api-key has no registered credential for the court, Judit returns application_error: SECRECY_RESTRICTED. To access, register the lawyer’s credential at Vault and reference it via customer_key in the query.
On 429, read X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset to adjust dispatching. For mass flows, adopt a sliding window.

Quick troubleshooting table

SymptomMost likely hypothesisNext step
HTTP 401 alwaysMissing api-key header / wrong value / space/line break.echo $JUDIT_API_KEY | wc -c — check the size.
HTTP 403 on a specific routeFeature not enabled in your plan.Talk to Judit at support@judit.io.
LAWSUIT_NOT_FOUND for an existing CNJCNJ is under secrecy.See Credentials Vault.
Webhook doesn’t arriveURL not public/HTTPS, or returning ≠ 2xx.See Webhook.
2 webhooks with same request_idExpected behavior — first comes from cache (cached_response: true), second from court.See cached_response.
Tracking with no new eventsrecurrence too high or notification_filters.step_terms too restrictive.Lower recurrence; relax filters.
Empty name responseHomonym or accented name.Search by CPF/CNPJ; remove accents for testing.

Next steps

  • 👉 Rate Limits — Retry with Exponential Backoff function to handle 429.
  • 👉 Authentication — how to send credentials correctly to avoid 401.
  • 👉 Webhook & Callbacks — redelivery behavior and idempotency.
  • 👉 Glossary — technical terms referenced here.
  • 👉 FAQ — frequently asked questions.