Gå til indholdet

API-reference

Redact-API

Pseudonymise text, find personal data and put the originals back. Send short texts synchronously and long documents as encrypted text jobs; PDF and Word files are in beta. Organisation integration keys and personal keys both work here.

Basisadresse
https://api.komplai.dk

Pseudonymise a text

POST /v1/redact

Replaces personal data with labels such as [PERSON-1] and returns the pseudonymised text in redacted. Choose the layers in detectors: regex (rules for CPR numbers, phone numbers, e-mail addresses and more), ner (a model for names, organisations and addresses) and llm (a language model for what rules and NER miss, such as health data in free text). Without detectors, regex and ner run. Rules run on komplai's servers in Germany (EU), and NER at the place in nerDeployment or, without one, at the default place GET /v1/access marks. The language model runs on komplai's local infrastructure in Denmark by default; processing eu-cloud uses komplai's EU cloud, needs llm in detectors and EU processing approved for your organisation, and counts towards the organisation's monthly AI spending cap. Your organisation's own redaction rules always apply.

Use this call for short texts such as a letter or a note: at most 750,000 UTF-16 code units, and work that finishes within 300 seconds. Before anything runs, the call estimates the time from komplai's measured speeds with an empty queue; a run whose estimate exceeds the hold is refused with 413 use_job, its estimatedSeconds and holdSeconds, and nothing is processed or charged. The estimate cannot cover an EU language model, which has no measured speed yet, time spent waiting in the shared queue, or a text that takes longer than a typical one: such a run can still reach the hold and end with 504 processing_timeout and no result, and calls already sent to the EU cloud count towards the monthly AI spending cap. Send long texts and EU runs as a text job (POST /v1/redact/jobs), or send this call with the header Prefer: respond-async to get 202 and a job instead. Without that header the call never turns into a job. PDF and Word files go to POST /v1/redact/file. Ask for include reports only when you need them: they contain the originals. A failed call returns no partial result. engine agentic (preview) requires the organisation administrator's opt-in (403 when absent) and processing local; it reads up to 2,000,000 UTF-16 code units as a job, while a synchronous call takes what it can finish in time. External lookups require explicit per-run sources and the administrator's current source permission. No method guarantees anonymity; check the result.

Organisation integration keys cannot use engine agentic: 403 integration_not_permitted.

Scopes
redact:process
Prøv kaldet

Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.

En nøgle, der starter med kp_org_ eller kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.

Parametre

Headere

  • prefer string

    Optional. respond-async answers 202 with a text job, exactly as POST /v1/redact/jobs, instead of holding the connection; the answer carries Preference-Applied: respond-async. Without it the call never becomes a job. Ignored while text jobs are not accepted.

    En af
    respond-async
  • idempotency-key string

    Optional. A new UUID for each job, in upper or lower case. If the connection drops, send the same request again with the same key: within the job's lifetime the same key and body return the same job (reused true) instead of a second one, and the same key with another body answers 409 idempotency_conflict. Never reuse a key for another text. The key is bound to your organisation, the owner (person or integration) and the API key. The default {{$guid}} is Postman's variable for a new UUID on each request; in other tools, generate a UUID for each job or leave the header out.

    Standard
    {{$guid}}
    Format
    uuid

Body i kaldet

  • text string påkrævet

    The exact text to pseudonymise: non-blank, valid Unicode, without NUL. At most 750,000 UTF-16 code units, as in JavaScript and .NET; every offset in the response counts the same way.

    Længde
    1 til 750.000
  • detectors string[]

    The layers to run, in any non-empty combination. regex: rules for CPR numbers, phone numbers, e-mail addresses and more. ner: a model for names, organisations and addresses. llm: a language model for what rules and NER miss, such as health data in free text; it can take up to a minute. It reads the text in parts of at most 12,000 characters. When its answer for a part cannot be used, that answer is discarded and the part is asked again in two overlapping halves, down to halves of 1,500 characters: at most 14 extra calls for a part. If an answer still cannot be used, the call fails with 502 invalid_detection or incomplete_detection and returns no result. Default regex and ner. The older field mode is still accepted but is not listed here: leave it out, because if you send both, they must agree (400 unsupported_engine_mode). engine agentic needs regex and llm, with optional ner.

    Standard
    ["regex", "ner"]
    Elementer
    1 til 3
    Unikke elementer
    Hvert element er en af
    regex ner llm
  • processing string

    Where the language model (llm) runs. local (default): komplai's local infrastructure in Denmark, with no AI charge. eu-cloud: komplai's EU cloud, which answers faster. It needs llm in detectors and EU processing approved for your organisation, and its usage counts towards the organisation's monthly AI spending cap (429 ai_credit_exhausted when the cap is reached). Every call to the model, including a part asked again in halves, is checked against the cap and counted on its own. Name the model in model, or leave it out for the default model there. Rules always run on komplai's servers in Germany (EU), and NER at the place in nerDeployment or, without one, at the default place GET /v1/access marks. GET /v1/access names where each layer processes text for your organisation, including eu-cloud, in services[].hosting.processing.layers. The API never switches between local and eu-cloud by itself.

    En af
    local eu-cloud
    Standard
    local
  • nerDeployment string kan være null

    Where the ner layer runs: eu-de (komplai's servers in Germany, EU) or local (komplai's local infrastructure in Denmark). Leave it out, or send null, for the default place: the one GET /v1/access marks with default true in the ner layer's places (services[].hosting.processing.layers), eu-de unless komplai has changed it. Each place there has available and a reason for the operations with detectors, and detect with the same for POST /v1/redact/detect and the operations without detectors, so check that the place you name is available for the operation you call. A place that cannot be used now answers 503 ner_location_unavailable and names the place in nerDeployment; NER never moves to another place. Needs ner in detectors (400 ner_deployment_without_ner); any other value answers 400 invalid_ner_deployment. The response names the place in configuration.nerDeployment (nerDeployment on POST /v1/redact/detect).

    En af
    eu-de local
    Standard
    null
  • nerModel string kan være null

    The NER model, by id from the ner layer's models in GET /v1/access. Leave it out, or send null, for the default model. An unknown id answers 400 ner_model_unknown, and a retired one or one that does not run at the place you name 400 ner_model_unavailable; a preview model needs your organisation's Redact preview, which an organisation integration key does not have (403 ner_model_preview_required). POST /v1/redact/detect, and the text operations without detectors, run only the default model (400 ner_model_unavailable for another). A model that is not set up at the default place on this server answers 503 ner_model_unconfigured; NER never runs another model. Needs ner in detectors (400 ner_model_without_ner). The response names the model in configuration.nerModel (nerModel on POST /v1/redact/detect).

    Standard
    null
  • model string kan være null

    The language model for llm, by id from GET /v1/access: the models of the llm layer for the processing you choose. Leave it out, or send null, for the default model there. Only models validated for Redact at that processing are accepted (400 llm_model_not_validated): qwen3.8-27b-q8 for local and mistral-small-3.2-24b-instruct-2506 for eu-cloud. GET /v1/access also lists models with reason not_validated, which cannot be chosen. A local model that local infrastructure does not offer right now answers 503 local_model_unavailable, and an EU model your organisation's EU route does not have answers 409 model_not_enabled. Without model, the default must be validated too: on local the server's default model, on eu-cloud the EU model the person behind a personal key saved, else the model on your organisation's EU route (409 llm_model_not_validated). The API never picks another model. Needs llm in detectors and engine pipeline (400 llm_model_not_applicable). configuration.llmModel names the model that ran.

    Standard
    null
  • include string[]

    Extra reports. Each contains originals: protect the response as personal information. mapping: label to original, for POST /v1/redact/restore. changes: exact positions in your text and in redacted. findings: everything the layers found. skipped: CPR-shaped numbers the regex layer left in redacted because their digits do not decode to a plausible birth date, with the reason. A skipped number can still identify a person, for example an erstatningspersonnummer with day + 60. skipped is filled only when regex runs.

    Standard
    []
    Elementer
    højst 4
    Unikke elementer
    Hvert element er en af
    mapping findings changes skipped
  • policy string

    Always all-detected: everything found is replaced, under your organisation's redaction and allow rules.

    En af
    all-detected
    Standard
    all-detected
  • engine string Forhåndsversion

    Preview. Leave out. pipeline (default) runs the chosen detectors. agentic is an experimental method for organisations whose administrator has turned on the Redact Agentic preview (403 agentic_preview_not_enabled otherwise); an organisation integration key gets 403 integration_not_permitted. It needs processing local and detectors regex and llm, with optional ner. It reads the text in windows, so it takes the operation's own text limit; a long document belongs in a text job.

    En af
    pipeline agentic
    Standard
    pipeline
  • sources string[] Forhåndsversion

    Preview. Leave out. Lookup sources for engine agentic, chosen for each call. Each needs the administrator's approval and configured access; an unapproved or unavailable source refuses the call (403 agentic_lookup_not_allowed or 503 agentic_lookup_unavailable) and is never silently dropped. Default none.

    Standard
    []
    Elementer
    højst 5
    Unikke elementer
    Hvert element er en af
    cvr-official bbr web dar wikidata-local

Svar

200 OK

The pseudonymised text and what ran. The include reports you asked for contain originals.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid

Body

  • engine string påkrævet
    En af
    pipeline agentic
  • redacted string påkrævet

    The pseudonymised text, with labels such as [PERSON-1]. The same original gets the same label throughout the text.

  • mode string påkrævet
    En af
    regex ner semantic
  • processing string påkrævet

    Where the language model ran, or would have run.

    En af
    local eu-cloud
  • policy string påkrævet
    En af
    all-detected
  • policyVersion string påkrævet
    En af
    redact-text-v1
  • offsetEncoding string påkrævet

    Every offset counts UTF-16 code units.

    En af
    utf-16
  • charsIn integer påkrævet

    Length of your text in UTF-16 code units.

    Værdi
    1 til 2.000.000
  • charsOut integer påkrævet

    Length of redacted in UTF-16 code units.

    Værdi
    mindst 0
  • truncated boolean påkrævet

    Always false: a truncated detection fails the call instead.

    En af
    false
  • degraded boolean påkrævet

    Always false: a degraded detection fails the call instead.

    En af
    false
  • configuration object

    The choices that took effect. llmModel names the language model when it is known, and llmReasoningEffort the reasoning effort it was sent: by the llm layer, and on eu-cloud by mode semantic without detectors too. nerModel and nerDeployment name the NER model and place when you chose them, and nerDeployment also when NER ran at another place than eu-de.

    Underfelter (9)
    • engine string påkrævet
      En af
      pipeline agentic
    • mode string påkrævet
      En af
      regex ner semantic
    • detectors string[] påkrævet
      Hvert element er en af
      regex ner llm
    • sources string[] påkrævet
      Hvert element er en af
      cvr-official bbr web dar wikidata-local
    • processing string påkrævet
      En af
      local eu-cloud
    • nerModel string

      The NER model you named in nerModel.

    • nerDeployment string

      Where NER ran: present when you named the place, or when NER ran somewhere other than eu-de.

      En af
      eu-de local
    • llmModel string

      The language model that answered, when it is known.

    • llmReasoningEffort string

      The reasoning effort the language model was sent: by the llm layer of the pipeline engine, and on eu-cloud by mode semantic without detectors too. komplai sets it per model when it validates the model for Redact; none means no reasoning.

      En af
      none low medium high xhigh max
  • execution object

    What actually ran: detectorsRun lists the layers, and the counts appear when they were measured. A missing count does not mean zero. llmOccurrenceRepairs counts llm findings whose quote occurs once in the text but whose occurrence number pointed past it; each was placed on that one match. llmResolvedFindings counts llm findings whose quote could not be placed exactly and that were placed on every span equal to the quote once spacing and line breaks, invisible characters, typographic quotes and dashes, and for quotes of two or more words or with a digit, letter case are ignored; each is an exact span of the text. llmWindows counts the language model's answers the result is made of. llmSplits counts answers that could not be used and were discarded; each made two more calls, one for each half of its part of the text.

    Underfelter (13)
    • completed boolean påkrævet
      En af
      true
    • detectorsRun string[] påkrævet
      Hvert element er en af
      regex ner llm
    • detectionPasses integer
      Værdi
      mindst 0
    • nerCalls integer
      Værdi
      mindst 0
    • llmCalls integer
      Værdi
      mindst 0
    • llmOccurrenceRepairs integer
      Værdi
      mindst 0
    • llmResolvedFindings integer
      Værdi
      mindst 0
    • llmWindows integer
      Værdi
      mindst 0
    • llmSplits integer
      Værdi
      mindst 0
    • toolCalls integer
      Værdi
      mindst 0
    • rounds integer
      Værdi
      mindst 0
    • documentCoverageComplete boolean
    • releaseReviewComplete boolean
  • mapping map<string>

    Label to canonical original mention. Use changes for exact source reconstruction.

    Underfelter (1)
    • Vilkårlig nøgle string
  • entries object[]

    Returned with mapping: one entry per label, with its type, original, confidence and source layer.

    Underfelter (5)
    • placeholder string påkrævet
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • value string påkrævet
    • confidence string påkrævet
      En af
      high medium low
    • source string påkrævet

      The layer that found it: regex (the rules), ner, llm (the language model) or custom (your organisation's own redaction rules). Always present.

      En af
      regex ner llm custom
  • findings object[]

    Everything the layers found, with offsets in your text and the layer that found each in source.

    Underfelter (9)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • value string påkrævet
    • confidence string påkrævet
      En af
      high medium low
    • source string påkrævet

      The layer that found it: regex (the rules), ner, llm (the language model) or custom (your organisation's own redaction rules). Always present.

      En af
      regex ner llm custom
    • customLabel string
      Længde
      højst 64
    • replacementToken string
      Længde
      højst 128
    • entityId string
  • changes object[]

    Each replacement with its offsets in your text (start, end) and in redacted (outputStart, outputEnd). Apply them in reverse order of outputStart to rebuild your exact text.

    Underfelter (7)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • outputStart integer påkrævet
      Værdi
      mindst 0
    • outputEnd integer påkrævet
      Værdi
      mindst 1
    • original string påkrævet
    • replacement string påkrævet
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
  • skipped object[]

    CPR-shaped numbers the regex layer declined and no final change covers, with a reason code and an English explanation. They remain in redacted and can still identify a person, for example an erstatningspersonnummer with day + 60 (reported as cpr_invalid_date). Empty when the regex layer did not run (NER- or LLM-only detectors, or engine agentic).

    Underfelter (6)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • value string påkrævet
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • reason string påkrævet
      En af
      cpr_unknown_century cpr_birth_year_out_of_range cpr_invalid_date
    • detail string påkrævet
      Længde
      højst 200
202 Accepted

Only with Prefer: respond-async: the text is a job. Location points to its status; poll it, then read the result.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Location string

    The job's status: /v1/redact/jobs/{id}.

  • Preference-Applied string

    respond-async

    En af
    respond-async

Body

  • id string påkrævet
    Format
    uuid
  • state string påkrævet
    En af
    queued running succeeded failed cancelled invalidated
  • createdAt string påkrævet
    Format
    date-time
  • expiresAt string påkrævet

    Application retention deadline. A queued job expires this long after it was submitted; a running job is kept for as long as its worker is alive; when the job ends, the retention period counts from the end. Results remain encrypted until explicit deletion or expiry; reads do not consume them.

    Format
    date-time
  • progress object påkrævet
    Underfelter (2)
    • completed integer påkrævet
      Værdi
      mindst 0
    • total integer påkrævet
      Værdi
      mindst 0
  • error string
  • reused boolean
400 Bad Request

The request was refused before processing.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Fejlkoder

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.
  • invalid_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Fejlkoder

  • insufficient_scope The key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.
  • identity_retired The person behind a personal key has been removed from komplai.
  • processing_choice_not_allowed The organisation does not allow this processing (local infrastructure or EU cloud) through the API, or the connection is not made available through the API.
  • processing_not_enabled The processing is not enabled for the app in the organisation: EU processing is not approved and enabled, or the agreement keeps processing on local infrastructure.
  • processing_not_approved The organisation's processing approval for the app is missing or was withdrawn.
  • app_not_assigned The key's person lost the app or their membership while the request was admitted.
  • processing_access_changed The organisation's processing setup changed while the request was handled. Send it again.
  • ai_credit_not_granted No monthly AI spending cap is set up for this month, so eu-cloud cannot run.
  • ner_model_preview_required The NER model in nerModel is a preview. It needs your organisation's Redact preview, which an organisation integration key does not have.
  • integration_not_permitted An organisation integration key cannot use this operation or this option.
  • agentic_preview_not_enabled The organisation's administrator has not turned on the Redact Agentic preview.
  • agentic_lookup_not_allowed A source in sources is not approved by the organisation's administrator.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
409 Conflict

Conflict with the current state.

Fejlkoder

  • processing_policy_changed Your organisation's redaction rules changed while the request ran. Send it again.
  • model_not_enabled The model is not one you may use at this processing, or it is not offered there right now.
  • llm_model_not_validated The language model in model is not validated for Redact at the processing you chose. GET /v1/access lists the models you may name.
  • reasoning_effort_not_supported The reasoning effort komplai set for this EU language model in Redact is not one the model accepts on your organisation's EU route. Nothing was sent to the model, and the API does not send another effort.
  • processing_access_changed The organisation's processing setup changed while the request was handled. Send it again.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
413 Content Too Large

Too large.

Fejlkoder

  • text_too_large text is over the operation's limit in UTF-16 code units, or the body is over its byte limit.
  • use_job The run cannot finish within the 300 seconds a synchronous call may take. estimatedSeconds is komplai's estimate from its measured speeds, with an empty queue; holdSeconds is the limit. Nothing was processed or charged. Send the same body as a text job (POST /v1/redact/jobs), or this call with Prefer: respond-async.
  • processing_complexity_exceeded The text needs more work than its length allows: more candidate matches or matched characters than the per-character bounds in /v1/access, coreference matching work beyond its per-character bound (for example one name nested inside itself thousands of times), or more time for the organisation rules than their limit, which grows with the text and the number of rules. The bounds grow with the text, so splitting it rarely helps. Nothing partial is returned.
  • result_too_large The result would be over 32 MiB. Ask for fewer include reports or split the text.
  • context_limit The input and the requested output do not fit the model: max_tokens is over the model's limit, the input with max_tokens is over its context, or, in Redact, a part of the text does not fit even after it was asked again in halves down to 1,500 characters.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
415 Unsupported Media Type

The body has no Content-Type, or one the API does not read, such as XML or form data. Send application/json.

Fejlkoder

  • invalid_body The body is not a JSON object with the documented fields: invalid JSON, Content-Type text/plain, an unknown field, a field of the wrong type, or a required field that is missing or blank.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Fejlkoder

  • rate_limited Too many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.
  • ai_credit_exhausted The organisation's monthly AI spending cap for EU cloud is reached, or its own lower limit, or on a pilot the pilot's total allowance. Local processing keeps working.
  • person_ai_credit_exhausted Your personal AI limit is reached (personal keys only).
  • processing_capacity_busy All organisation-rule workers in this API process are busy. There is no queue: try again after Retry-After.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer påkrævet

    Seconds to wait before trying again (at most 60).

    Værdi
    1 til 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

502 Bad Gateway

A processing service failed. No partial result is returned.

Fejlkoder

  • incomplete_detection A detection layer did not finish the whole text. No partial result is returned.
  • invalid_detection A detection layer returned output that failed validation. For llm: an answer that still could not be used after its part of the text was asked again in halves down to 1,500 characters.
  • detection_service_unavailable The detection service could not be reached or failed.
  • unsafe_placeholder A fixed replacement token from your organisation's rules occurs in the text or collides with a label.
  • service_unavailable The model failed or could not be reached, or local infrastructure is not set up for this call right now.
  • invalid_response The model's answer failed validation, so nothing was returned.
  • agent_no_progress Redact Agentic stopped making progress: several rounds in a row read nothing new, found nothing and moved to no new step. No partial result is returned.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
503 Service Unavailable

Processing is not available right now.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
504 Gateway Timeout

The call timed out.

Fejlkoder

  • processing_timeout The call took more than 300 seconds, or the client disconnected. Send long texts as text jobs.
  • model_stalled The language model stopped answering: its connection was silent, or it ran past the time its answer needs at the model's measured speed. No partial result is returned.
  • model_queue_expired The language model's shared queue on local infrastructure did not reach this call before its deadline. Try again later, or send it as a text job, which waits for its turn.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
KaldPOST /v1/redact
curl
curl https://api.komplai.dk/v1/redact \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "text": "Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid.",
    "detectors": ["regex", "ner"],
    "include": ["mapping", "changes"]
  }'
PowerShell
$headers = @{
    Authorization = "Bearer $env:KOMPLAI_TOKEN"
}
$body = [ordered]@{
    text = 'Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid.'
    detectors = @('regex', 'ner')
    include = @('mapping', 'changes')
} | ConvertTo-Json -Depth 100

$request = @{
    Method = 'Post'
    Uri = 'https://api.komplai.dk/v1/redact'
    Headers = $headers
    ContentType = 'application/json; charset=utf-8'
    Body = $body
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100
Python
import os

import requests

response = requests.post(
    "https://api.komplai.dk/v1/redact",
    headers={
        "Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
    },
    json={
        "text": "Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid.",
        "detectors": ["regex", "ner"],
        "include": ["mapping", "changes"],
    },
    timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())
JavaScript
const response = await fetch("https://api.komplai.dk/v1/redact", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    text: "Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid.",
    detectors: ["regex", "ner"],
    include: ["mapping", "changes"],
  }),
});

console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.komplai.dk/v1/redact");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));
request.Content = new StringContent(@"{
  ""text"": ""Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid."",
  ""detectors"": [""regex"", ""ner""],
  ""include"": [""mapping"", ""changes""]
}", Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
    Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());

Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.

Svar
200 OK
{
  "redacted": "Borgeren [PERSON-1], cpr-nr. [CPR-1], bor på [ADRESSE-1]. Hun kan kontaktes på [TLF-1] eller [EMAIL-1].",
  "engine": "pipeline",
  "mode": "ner",
  "processing": "local",
  "policy": "all-detected",
  "policyVersion": "redact-text-v1",
  "offsetEncoding": "utf-16",
  "charsIn": 154,
  "charsOut": 103,
  "truncated": false,
  "degraded": false,
  "configuration": {
    "engine": "pipeline",
    "mode": "ner",
    "detectors": ["regex", "ner"],
    "sources": [],
    "processing": "local"
  },
  "execution": {
    "completed": true,
    "detectorsRun": ["regex", "ner"],
    "detectionPasses": 1,
    "nerCalls": 1,
    "llmCalls": 0
  },
  "mapping": {
    "[PERSON-1]": "Mette Kjærgaard Holm",
    "[CPR-1]": "120385-1234",
    "[ADRESSE-1]": "Fiktivvej 12, 8000 Aarhus C",
    "[TLF-1]": "21 34 56 78",
    "[EMAIL-1]": "mette.holm@example.invalid"
  },
  "entries": [
    {
      "placeholder": "[PERSON-1]",
      "type": "person",
      "value": "Mette Kjærgaard Holm",
      "confidence": "medium",
      "source": "ner"
    },
    {
      "placeholder": "[CPR-1]",
      "type": "cpr",
      "value": "120385-1234",
      "confidence": "high",
      "source": "regex"
    },
    {
      "placeholder": "[ADRESSE-1]",
      "type": "address",
      "value": "Fiktivvej 12, 8000 Aarhus C",
      "confidence": "high",
      "source": "ner"
    },
    {
      "placeholder": "[TLF-1]",
      "type": "phone",
      "value": "21 34 56 78",
      "confidence": "medium",
      "source": "regex"
    },
    {
      "placeholder": "[EMAIL-1]",
      "type": "email",
      "value": "mette.holm@example.invalid",
      "confidence": "high",
      "source": "regex"
    }
  ],
  "changes": [
    {
      "start": 9,
      "end": 29,
      "outputStart": 9,
      "outputEnd": 19,
      "original": "Mette Kjærgaard Holm",
      "replacement": "[PERSON-1]",
      "type": "person"
    },
    {
      "start": 39,
      "end": 50,
      "outputStart": 29,
      "outputEnd": 36,
      "original": "120385-1234",
      "replacement": "[CPR-1]",
      "type": "cpr"
    },
    {
      "start": 59,
      "end": 86,
      "outputStart": 45,
      "outputEnd": 56,
      "original": "Fiktivvej 12, 8000 Aarhus C",
      "replacement": "[ADRESSE-1]",
      "type": "address"
    },
    {
      "start": 109,
      "end": 120,
      "outputStart": 79,
      "outputEnd": 86,
      "original": "21 34 56 78",
      "replacement": "[TLF-1]",
      "type": "phone"
    },
    {
      "start": 127,
      "end": 153,
      "outputStart": 93,
      "outputEnd": 102,
      "original": "mette.holm@example.invalid",
      "replacement": "[EMAIL-1]",
      "type": "email"
    }
  ]
}
200 OK
{
  "redacted": "Borgeren [PERSON-1] bor på [ADRESSE-1].",
  "engine": "pipeline",
  "mode": "ner",
  "processing": "local",
  "policy": "all-detected",
  "policyVersion": "redact-text-v1",
  "offsetEncoding": "utf-16",
  "charsIn": 65,
  "charsOut": 39,
  "truncated": false,
  "degraded": false,
  "configuration": {
    "engine": "pipeline",
    "mode": "ner",
    "detectors": ["ner"],
    "sources": [],
    "processing": "local",
    "nerModel": "danish-pii-ner-v1.3.0",
    "nerDeployment": "eu-de"
  },
  "execution": {
    "completed": true,
    "detectorsRun": ["ner"],
    "detectionPasses": 1,
    "nerCalls": 1,
    "llmCalls": 0
  }
}
200 OK
{
  "redacted": "Sagsbehandleren talte med [PERSON-1] om hendes [HELBRED-1].",
  "engine": "pipeline",
  "mode": "semantic",
  "processing": "local",
  "policy": "all-detected",
  "policyVersion": "redact-text-v1",
  "offsetEncoding": "utf-16",
  "charsIn": 66,
  "charsOut": 59,
  "truncated": false,
  "degraded": false,
  "configuration": {
    "engine": "pipeline",
    "mode": "semantic",
    "detectors": ["regex", "ner", "llm"],
    "sources": [],
    "processing": "local",
    "llmModel": "qwen3.8-27b-q8"
  },
  "execution": {
    "completed": true,
    "detectorsRun": ["regex", "ner", "llm"],
    "detectionPasses": 1,
    "nerCalls": 1,
    "llmCalls": 1
  },
  "findings": [
    {
      "start": 26,
      "end": 46,
      "type": "person",
      "value": "Mette Kjærgaard Holm",
      "confidence": "medium",
      "source": "ner",
      "entityId": "person:Mette Kjærgaard Holm"
    },
    {
      "start": 57,
      "end": 65,
      "type": "health",
      "value": "diabetes",
      "confidence": "medium",
      "source": "llm"
    }
  ]
}
200 OK
{
  "redacted": "Sagsbehandleren talte med [PERSON-1] om hendes [HELBRED-1].",
  "engine": "pipeline",
  "mode": "semantic",
  "processing": "eu-cloud",
  "policy": "all-detected",
  "policyVersion": "redact-text-v1",
  "offsetEncoding": "utf-16",
  "charsIn": 66,
  "charsOut": 59,
  "truncated": false,
  "degraded": false,
  "configuration": {
    "engine": "pipeline",
    "mode": "semantic",
    "detectors": ["regex", "ner", "llm"],
    "sources": [],
    "processing": "eu-cloud",
    "llmModel": "mistral-small-3.2-24b-instruct-2506"
  },
  "execution": {
    "completed": true,
    "detectorsRun": ["regex", "ner", "llm"],
    "detectionPasses": 1,
    "nerCalls": 1,
    "llmCalls": 1
  },
  "mapping": {
    "[PERSON-1]": "Mette Kjærgaard Holm",
    "[HELBRED-1]": "diabetes"
  },
  "entries": [
    {
      "placeholder": "[PERSON-1]",
      "type": "person",
      "value": "Mette Kjærgaard Holm",
      "confidence": "medium",
      "source": "ner"
    },
    {
      "placeholder": "[HELBRED-1]",
      "type": "health",
      "value": "diabetes",
      "confidence": "medium",
      "source": "llm"
    }
  ]
}
200 OK
{
  "redacted": "Gammelt nummer 150677-8642, erstatningspersonnummer 720385-1234 og cpr-nr. [CPR-1].",
  "engine": "pipeline",
  "mode": "regex",
  "processing": "local",
  "policy": "all-detected",
  "policyVersion": "redact-text-v1",
  "offsetEncoding": "utf-16",
  "charsIn": 87,
  "charsOut": 83,
  "truncated": false,
  "degraded": false,
  "configuration": {
    "engine": "pipeline",
    "mode": "regex",
    "detectors": ["regex"],
    "sources": [],
    "processing": "local"
  },
  "execution": {
    "completed": true,
    "detectorsRun": ["regex"],
    "detectionPasses": 1,
    "nerCalls": 0,
    "llmCalls": 0
  },
  "skipped": [
    {
      "start": 15,
      "end": 26,
      "value": "150677-8642",
      "type": "cpr",
      "reason": "cpr_birth_year_out_of_range",
      "detail": "Birth year 1877 is before 1880"
    },
    {
      "start": 52,
      "end": 63,
      "value": "720385-1234",
      "type": "cpr",
      "reason": "cpr_invalid_date",
      "detail": "Day 72 does not exist in month 03 of 1985"
    }
  ]
}
202 Accepted
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "queued",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 0
  },
  "reused": false
}
400 Bad Request
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "insufficient_scope",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/insufficient_scope"
}
409 Conflict
{
  "error": "processing_policy_changed",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/processing_policy_changed"
}
413 Content Too Large
{
  "error": "text_too_large",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/text_too_large"
}
415 Unsupported Media Type
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
429 Too Many Requests
{
  "error": "rate_limited",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/rate_limited"
}
502 Bad Gateway
{
  "error": "incomplete_detection",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/incomplete_detection"
}
503 Service Unavailable
{
  "error": "ner_location_unavailable",
  "nerDeployment": "local",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/ner_location_unavailable"
}
504 Gateway Timeout
{
  "error": "processing_timeout",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/processing_timeout"
}

Find personal data in a text

POST /v1/redact/detect

Returns what regex and NER find, with UTF-16 offsets into your text, without changing it. At most 16,000 UTF-16 code units and 100,000 bytes per call; split longer texts or use POST /v1/redact. Rules run on komplai's servers in Germany (EU), and NER at the place you choose with nerDeployment or, without one, at the default place GET /v1/access marks (it lists the places). No language model runs here. Your organisation's own redaction rules apply, as on POST /v1/redact: a rule's match is returned with type and source custom and the rule's label in customLabel, and a finding that an allow rule covers is left out.

Scopes
redact:detect
Prøv kaldet

Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.

En nøgle, der starter med kp_org_ eller kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.

Body i kaldet

  • text string påkrævet

    The text to search: at least one character, at most 16,000 UTF-16 code units.

    Længde
    1 til 16.000
  • mode string

    ner (default): rules and NER. regex: rules only. Your organisation's own redaction rules apply in both.

    En af
    regex ner
    Standard
    ner
  • semantic boolean

    Leave out or send false. This operation runs no language model: true answers 400 unsupported_pilot_mode.

    En af
    false
    Standard
    false
  • nerDeployment string kan være null

    Where the ner layer runs: eu-de (komplai's servers in Germany, EU) or local (komplai's local infrastructure in Denmark). Leave it out, or send null, for the default place: the one GET /v1/access marks with default true in the ner layer's places (services[].hosting.processing.layers), eu-de unless komplai has changed it. Each place there has available and a reason for the operations with detectors, and detect with the same for POST /v1/redact/detect and the operations without detectors, so check that the place you name is available for the operation you call. A place that cannot be used now answers 503 ner_location_unavailable and names the place in nerDeployment; NER never moves to another place. Needs ner in detectors (400 ner_deployment_without_ner); any other value answers 400 invalid_ner_deployment. The response names the place in configuration.nerDeployment (nerDeployment on POST /v1/redact/detect).

    En af
    eu-de local
    Standard
    null
  • nerModel string kan være null

    The NER model, by id from the ner layer's models in GET /v1/access. Leave it out, or send null, for the default model. An unknown id answers 400 ner_model_unknown, and a retired one or one that does not run at the place you name 400 ner_model_unavailable; a preview model needs your organisation's Redact preview, which an organisation integration key does not have (403 ner_model_preview_required). POST /v1/redact/detect, and the text operations without detectors, run only the default model (400 ner_model_unavailable for another). A model that is not set up at the default place on this server answers 503 ner_model_unconfigured; NER never runs another model. Needs ner in detectors (400 ner_model_without_ner). The response names the model in configuration.nerModel (nerModel on POST /v1/redact/detect).

    Standard
    null

Svar

200 OK

What regex and NER found. The text itself is not changed or returned. When you named the NER place or model, nerDeployment and nerModel name what ran.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid

Body

  • findings object[] påkrævet
    Underfelter (6)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • value string påkrævet
    • confidence string påkrævet
      En af
      high medium low
    • source string påkrævet

      The layer that found it: regex (the rules), ner, or custom (your organisation's own redaction rules). Always present.

      En af
      regex ner custom
  • truncated boolean påkrævet
    En af
    false
  • degraded boolean påkrævet
    En af
    false
  • nerDeployment string

    When you chose a place: the place NER ran.

    En af
    eu-de local
  • nerModel string

    When you chose a model: the NER model that ran.

400 Bad Request

The request was refused before processing.

Fejlkoder

  • invalid_body The body is not a JSON object with the documented fields: invalid JSON, Content-Type text/plain, an unknown field, a field of the wrong type, or a required field that is missing or blank.
  • unsupported_pilot_mode mode is not regex or ner, or semantic is true. No language model runs on this operation.
  • invalid_ner_deployment nerDeployment is not eu-de or local.
  • ner_deployment_without_ner nerDeployment was sent, but ner is not in detectors (or mode is regex).
  • ner_model_without_ner nerModel was sent, but ner is not in detectors (or mode is regex).
  • ner_model_unknown No NER model has the id in nerModel. GET /v1/access lists the models you may choose.
  • ner_model_unavailable The NER model in nerModel is retired or does not run at the chosen place. A model other than the default also needs detectors.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Fejlkoder

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.
  • invalid_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Fejlkoder

  • insufficient_scope The key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.
  • identity_retired The person behind a personal key has been removed from komplai.
  • processing_choice_not_allowed The organisation does not allow this processing (local infrastructure or EU cloud) through the API, or the connection is not made available through the API.
  • processing_not_enabled The processing is not enabled for the app in the organisation: EU processing is not approved and enabled, or the agreement keeps processing on local infrastructure.
  • processing_not_approved The organisation's processing approval for the app is missing or was withdrawn.
  • app_not_assigned The key's person lost the app or their membership while the request was admitted.
  • ner_model_preview_required The NER model in nerModel is a preview. It needs your organisation's Redact preview, which an organisation integration key does not have.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
413 Content Too Large

Too large.

Fejlkoder

  • exceeds_ner_window text is over 16,000 UTF-16 code units, or the body is over 100,000 bytes. Use POST /v1/redact for longer texts.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
415 Unsupported Media Type

The body has no Content-Type, or one the API does not read, such as XML or form data. Send application/json.

Fejlkoder

  • invalid_body The body is not a JSON object with the documented fields: invalid JSON, Content-Type text/plain, an unknown field, a field of the wrong type, or a required field that is missing or blank.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Fejlkoder

  • rate_limited Too many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer påkrævet

    Seconds to wait before trying again (at most 60).

    Værdi
    1 til 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

502 Bad Gateway

A processing service failed. No partial result is returned.

Fejlkoder

  • detection_service_unavailable The detection service could not be reached or failed.
  • invalid_detection A detection layer returned output that failed validation. For llm: an answer that still could not be used after its part of the text was asked again in halves down to 1,500 characters.
  • incomplete_detection A detection layer did not finish the whole text. No partial result is returned.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
503 Service Unavailable

Processing is not available right now.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
KaldPOST /v1/redact/detect
curl
curl https://api.komplai.dk/v1/redact/detect \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "text": "Ring til Mette Kjærgaard Holm på 21 34 56 78.",
    "mode": "ner"
  }'
PowerShell
$headers = @{
    Authorization = "Bearer $env:KOMPLAI_TOKEN"
}
$body = [ordered]@{
    text = 'Ring til Mette Kjærgaard Holm på 21 34 56 78.'
    mode = 'ner'
} | ConvertTo-Json -Depth 100

$request = @{
    Method = 'Post'
    Uri = 'https://api.komplai.dk/v1/redact/detect'
    Headers = $headers
    ContentType = 'application/json; charset=utf-8'
    Body = $body
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100
Python
import os

import requests

response = requests.post(
    "https://api.komplai.dk/v1/redact/detect",
    headers={
        "Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
    },
    json={
        "text": "Ring til Mette Kjærgaard Holm på 21 34 56 78.",
        "mode": "ner",
    },
    timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())
JavaScript
const response = await fetch("https://api.komplai.dk/v1/redact/detect", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    text: "Ring til Mette Kjærgaard Holm på 21 34 56 78.",
    mode: "ner",
  }),
});

console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.komplai.dk/v1/redact/detect");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));
request.Content = new StringContent(@"{
  ""text"": ""Ring til Mette Kjærgaard Holm på 21 34 56 78."",
  ""mode"": ""ner""
}", Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
    Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());

Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.

Svar
200 OK
{
  "findings": [
    {
      "start": 9,
      "end": 29,
      "type": "person",
      "value": "Mette Kjærgaard Holm",
      "confidence": "high",
      "source": "ner"
    },
    {
      "start": 33,
      "end": 44,
      "type": "phone",
      "value": "21 34 56 78",
      "confidence": "medium",
      "source": "regex"
    }
  ],
  "truncated": false,
  "degraded": false
}
200 OK
{
  "findings": [
    {
      "start": 9,
      "end": 29,
      "type": "person",
      "value": "Mette Kjærgaard Holm",
      "confidence": "high",
      "source": "ner"
    },
    {
      "start": 33,
      "end": 44,
      "type": "phone",
      "value": "21 34 56 78",
      "confidence": "medium",
      "source": "regex"
    }
  ],
  "truncated": false,
  "degraded": false,
  "nerDeployment": "eu-de"
}
400 Bad Request
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "insufficient_scope",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/insufficient_scope"
}
413 Content Too Large
{
  "error": "exceeds_ner_window",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/exceeds_ner_window"
}
415 Unsupported Media Type
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
429 Too Many Requests
{
  "error": "rate_limited",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/rate_limited"
}
502 Bad Gateway
{
  "error": "detection_service_unavailable",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/detection_service_unavailable"
}
503 Service Unavailable
{
  "error": "ner_location_unavailable",
  "nerDeployment": "local",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/ner_location_unavailable"
}

Restore the originals in a text

POST /v1/redact/restore

Puts the originals back into text with labels such as [PERSON-1], for example an answer from your own model or workflow step. Send either the mapping from POST /v1/redact (asked for with include ["mapping"]) or the id of your own finished text job; with a job, komplai reads its retained result and you do not hold the mapping. Labels match regardless of case and spaces inside the brackets. Labels the mapping does not contain stay unchanged and are listed in unknownPlaceholders. Fixed replacement tokens from your organisation's redaction rules can stand for several originals, so they are never restored; those in the text are listed in fixedTokens. No model runs and the call has no AI charge; it counts against your request rate. The response contains originals: protect it as personal information.

Scopes
redact:process
Prøv kaldet

Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.

En nøgle, der starter med kp_org_ eller kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.

Body i kaldet

Body har en af disse former.

  • With mapping
    • text string påkrævet

      Text with labels such as [PERSON-1], for example an answer from your own model. Non-blank valid Unicode without NUL; the limit counts UTF-16 code units.

      Længde
      1 til 750.000
    • mapping map<string> påkrævet

      Label to original, as POST /v1/redact returns it with include ["mapping"]; send it unchanged. Keys in the exact [LABEL-N] form are restored. Any other key is a fixed replacement token from your organisation's redaction rules, such as [SAGSNR]: it can stand for several originals, so it is never restored and is listed in fixedTokens when the text contains it. Keys hold at most 128 UTF-16 code units without surrounding spaces, with at most 500 fixed tokens. Keys and values together may hold 2,000,000 UTF-16 code units. Send either mapping or job. At most 100,000 entries.

      Underfelter (1)
      • Vilkårlig nøgle string
        Længde
        mindst 1
  • With job
    • text string påkrævet

      Text with labels such as [PERSON-1], for example an answer from your own model. Non-blank valid Unicode without NUL; the limit counts UTF-16 code units.

      Længde
      1 til 750.000
    • job string påkrævet

      Id of your own finished job from POST /v1/redact/jobs, submitted with include ["mapping"] or ["changes"]. komplai reads the retained result, so you do not hold the mapping. Send either job or mapping.

      Format
      uuid

Svar

200 OK

The text with the originals put back. It contains personal data; protect it like the source document.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid

Body

  • text string påkrævet

    The text with originals put back. It contains personal information; protect it like the source document.

  • restored integer påkrævet

    Number of label occurrences replaced.

    Værdi
    mindst 0
  • unknownPlaceholders string[] påkrævet

    Labels found in the text that the mapping does not contain, in [LABEL-N] form and sorted. They are left unchanged. A label that does not start with a letter, such as [2026_SAG-2], is listed only when the mapping uses that label, so ranges such as [1-3] are not.

    Unikke elementer
  • ambiguousPlaceholders string[]

    Only for a job kept with changes and without mapping: restored labels that stood for more than one spelling in the source. The first spelling was used.

    Unikke elementer
  • fixedTokens string[]

    Fixed replacement tokens from the mapping or job, such as [SAGSNR], that occur in the text you sent. A fixed token can stand for several originals, so it is never restored and stays unchanged. Sorted; present only when not empty.

    Unikke elementer
400 Bad Request

The request was refused before processing.

Fejlkoder

  • invalid_body The body is not a JSON object with the documented fields: invalid JSON, Content-Type text/plain, an unknown field, a field of the wrong type, or a required field that is missing or blank.
  • invalid_text_encoding text contains NUL or a lone UTF-16 surrogate.
  • invalid_restore_source Send exactly one of mapping and job.
  • invalid_job job is not a UUID.
  • invalid_mapping mapping is not an object, or a value is empty, not a string, or contains NUL or a lone surrogate.
  • invalid_placeholder A mapping key is empty, longer than 128 UTF-16 code units, has surrounding spaces, contains NUL or a lone surrogate, or is `__proto__`, `constructor` or `prototype`.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Fejlkoder

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.
  • invalid_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Fejlkoder

  • insufficient_scope The key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.
  • identity_retired The person behind a personal key has been removed from komplai.
  • processing_access_withdrawn Access to the job was withdrawn after it was created: the agreement, the processing setup, the organisation's redaction rules or the storage policy for text jobs changed. The job is invalidated and its text and result are deleted. This is final: stop reading the job and do not reuse its Idempotency-Key; submit the text again as a new job when access allows it.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
404 Not Found

Not found.

Fejlkoder

  • not_found No job with this id for this key. A job is visible only to the key that created it, and it disappears when it expires.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
409 Conflict

Conflict with the current state.

Fejlkoder

  • job_not_finished The job is still queued or running; state says which. Try again after Retry-After seconds.
  • mapping_not_available The job kept neither mapping nor changes; hint says how to submit it again.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer

    With job_not_finished: seconds to wait before trying again.

    En af
    2
410 Gone

The job ended without a result. error is the job's code (see GET /v1/redact/jobs/{id}) and state its state.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
413 Content Too Large

Too large.

Fejlkoder

  • text_too_large text is over the operation's limit in UTF-16 code units, or the body is over its byte limit.
  • restore_too_large The body, the mapping (more than 100,000 entries, more than 2,000,000 UTF-16 code units or more than 500 fixed tokens) or the restored text (over 8,000,000 UTF-16 code units) is too large.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
415 Unsupported Media Type

The body has no Content-Type, or one the API does not read, such as XML or form data. Send application/json.

Fejlkoder

  • invalid_body The body is not a JSON object with the documented fields: invalid JSON, Content-Type text/plain, an unknown field, a field of the wrong type, or a required field that is missing or blank.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Fejlkoder

  • rate_limited Too many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer påkrævet

    Seconds to wait before trying again (at most 60).

    Værdi
    1 til 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

503 Service Unavailable

Processing is not available right now.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
KaldPOST /v1/redact/restore
curl
curl https://api.komplai.dk/v1/redact/restore \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "text": "Kære [PERSON-1]. Vi har modtaget din ansøgning og svarer på [EMAIL-1].",
    "mapping": {
      "[PERSON-1]": "Mette Kjærgaard Holm",
      "[CPR-1]": "120385-1234",
      "[ADRESSE-1]": "Fiktivvej 12, 8000 Aarhus C",
      "[TLF-1]": "21 34 56 78",
      "[EMAIL-1]": "mette.holm@example.invalid"
    }
  }'
PowerShell
$headers = @{
    Authorization = "Bearer $env:KOMPLAI_TOKEN"
}
$body = [ordered]@{
    text = 'Kære [PERSON-1]. Vi har modtaget din ansøgning og svarer på [EMAIL-1].'
    mapping = [ordered]@{
        '[PERSON-1]' = 'Mette Kjærgaard Holm'
        '[CPR-1]' = '120385-1234'
        '[ADRESSE-1]' = 'Fiktivvej 12, 8000 Aarhus C'
        '[TLF-1]' = '21 34 56 78'
        '[EMAIL-1]' = 'mette.holm@example.invalid'
    }
} | ConvertTo-Json -Depth 100

$request = @{
    Method = 'Post'
    Uri = 'https://api.komplai.dk/v1/redact/restore'
    Headers = $headers
    ContentType = 'application/json; charset=utf-8'
    Body = $body
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100
Python
import os

import requests

response = requests.post(
    "https://api.komplai.dk/v1/redact/restore",
    headers={
        "Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
    },
    json={
        "text": "Kære [PERSON-1]. Vi har modtaget din ansøgning og svarer på [EMAIL-1].",
        "mapping": {
            "[PERSON-1]": "Mette Kjærgaard Holm",
            "[CPR-1]": "120385-1234",
            "[ADRESSE-1]": "Fiktivvej 12, 8000 Aarhus C",
            "[TLF-1]": "21 34 56 78",
            "[EMAIL-1]": "mette.holm@example.invalid",
        },
    },
    timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())
JavaScript
const response = await fetch("https://api.komplai.dk/v1/redact/restore", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    text: "Kære [PERSON-1]. Vi har modtaget din ansøgning og svarer på [EMAIL-1].",
    mapping: {
      "[PERSON-1]": "Mette Kjærgaard Holm",
      "[CPR-1]": "120385-1234",
      "[ADRESSE-1]": "Fiktivvej 12, 8000 Aarhus C",
      "[TLF-1]": "21 34 56 78",
      "[EMAIL-1]": "mette.holm@example.invalid",
    },
  }),
});

console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.komplai.dk/v1/redact/restore");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));
request.Content = new StringContent(@"{
  ""text"": ""Kære [PERSON-1]. Vi har modtaget din ansøgning og svarer på [EMAIL-1]."",
  ""mapping"": {
    ""[PERSON-1]"": ""Mette Kjærgaard Holm"",
    ""[CPR-1]"": ""120385-1234"",
    ""[ADRESSE-1]"": ""Fiktivvej 12, 8000 Aarhus C"",
    ""[TLF-1]"": ""21 34 56 78"",
    ""[EMAIL-1]"": ""mette.holm@example.invalid""
  }
}", Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
    Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());

Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.

Svar
200 OK
{
  "text": "Kære Mette Kjærgaard Holm. Vi har modtaget din ansøgning og svarer på mette.holm@example.invalid.",
  "restored": 2,
  "unknownPlaceholders": []
}
400 Bad Request
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "insufficient_scope",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/insufficient_scope"
}
404 Not Found
{
  "error": "not_found",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/not_found"
}
409 Conflict
{
  "error": "job_not_finished",
  "state": "running",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/job_not_finished"
}
410 Gone
{
  "error": "redact_job_cancelled",
  "state": "cancelled",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/redact_job_cancelled"
}
413 Content Too Large
{
  "error": "text_too_large",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/text_too_large"
}
415 Unsupported Media Type
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
429 Too Many Requests
{
  "error": "rate_limited",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/rate_limited"
}
503 Service Unavailable
{
  "error": "redact_job_integrity_failed",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/redact_job_integrity_failed"
}

Submit a text job

POST /v1/redact/jobs

Stores the text encrypted and pseudonymises it in the background with the same options as POST /v1/redact, up to 2,000,000 UTF-16 code units (about 800 standard pages of 2,400 characters). Use it for long documents, also below the 300-second limit of a synchronous call. The answer is 202 with the job's id, and Location points to its status. Poll GET /v1/redact/jobs/{id}, at most every few seconds because reads count against the request limit, then read GET /v1/redact/jobs/{id}/result. Ask for include mapping or changes if you want to restore from the job with POST /v1/redact/restore. Personal data needs an approved storage policy for text jobs; the result stays encrypted until you delete the job or it expires, and the retention period counts from when the job ends. A job has no time limit of its own while it makes progress: it waits for the shared queue, every model call has a budget from the model's measured speed, and a job that makes no progress for 65 minutes fails with redact_job_stalled. A job belongs to the key that created it. A NER place or local language model the job names is checked against the settings when it is submitted, and whether it answers when the job runs; one that does not answer then fails the job with its code. A job that is interrupted (a restart or a lost worker) resumes from its encrypted checkpoint and sends at most the step that was in flight again: a call to the language model on local infrastructure gets its answer back from the queue when the queue finished it, and runs once more when the interruption cut it off, a call to the EU cloud is sent again once and counted towards the monthly AI spending cap like any call, and a register lookup is sent again; each is logged. After three interruptions the job ends with redact_job_attempts_exhausted. engine agentic (preview) requires the organisation administrator's opt-in (403 when absent) and processing local, and reads up to the same 2,000,000 UTF-16 code units in windows; external sources require explicit per-run selection and current administrator permission.

Organisation integration keys cannot use engine agentic: 403 integration_not_permitted.

Scopes
redact:process
Prøv kaldet

Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.

En nøgle, der starter med kp_org_ eller kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.

Parametre

Headere

  • idempotency-key string

    Optional. A new UUID for each job, in upper or lower case. If the connection drops, send the same request again with the same key: within the job's lifetime the same key and body return the same job (reused true) instead of a second one, and the same key with another body answers 409 idempotency_conflict. Never reuse a key for another text. The key is bound to your organisation, the owner (person or integration) and the API key. The default {{$guid}} is Postman's variable for a new UUID on each request; in other tools, generate a UUID for each job or leave the header out.

    Standard
    {{$guid}}
    Format
    uuid

Body i kaldet

  • text string påkrævet

    The exact text to pseudonymise: non-blank, valid Unicode, without NUL. At most 2,000,000 UTF-16 code units, as in JavaScript and .NET; every offset in the response counts the same way.

    Længde
    1 til 2.000.000
  • detectors string[]

    The layers to run, in any non-empty combination. regex: rules for CPR numbers, phone numbers, e-mail addresses and more. ner: a model for names, organisations and addresses. llm: a language model for what rules and NER miss, such as health data in free text; it can take up to a minute. It reads the text in parts of at most 12,000 characters. When its answer for a part cannot be used, that answer is discarded and the part is asked again in two overlapping halves, down to halves of 1,500 characters: at most 14 extra calls for a part. If an answer still cannot be used, the call fails with 502 invalid_detection or incomplete_detection and returns no result. Default regex and ner. The older field mode is still accepted but is not listed here: leave it out, because if you send both, they must agree (400 unsupported_engine_mode). engine agentic needs regex and llm, with optional ner.

    Standard
    ["regex", "ner"]
    Elementer
    1 til 3
    Unikke elementer
    Hvert element er en af
    regex ner llm
  • processing string

    Where the language model (llm) runs. local (default): komplai's local infrastructure in Denmark, with no AI charge. eu-cloud: komplai's EU cloud, which answers faster. It needs llm in detectors and EU processing approved for your organisation, and its usage counts towards the organisation's monthly AI spending cap (429 ai_credit_exhausted when the cap is reached). Every call to the model, including a part asked again in halves, is checked against the cap and counted on its own. Name the model in model, or leave it out for the default model there. Rules always run on komplai's servers in Germany (EU), and NER at the place in nerDeployment or, without one, at the default place GET /v1/access marks. GET /v1/access names where each layer processes text for your organisation, including eu-cloud, in services[].hosting.processing.layers. The API never switches between local and eu-cloud by itself.

    En af
    local eu-cloud
    Standard
    local
  • nerDeployment string kan være null

    Where the ner layer runs: eu-de (komplai's servers in Germany, EU) or local (komplai's local infrastructure in Denmark). Leave it out, or send null, for the default place: the one GET /v1/access marks with default true in the ner layer's places (services[].hosting.processing.layers), eu-de unless komplai has changed it. Each place there has available and a reason for the operations with detectors, and detect with the same for POST /v1/redact/detect and the operations without detectors, so check that the place you name is available for the operation you call. A place that cannot be used now answers 503 ner_location_unavailable and names the place in nerDeployment; NER never moves to another place. Needs ner in detectors (400 ner_deployment_without_ner); any other value answers 400 invalid_ner_deployment. The response names the place in configuration.nerDeployment (nerDeployment on POST /v1/redact/detect).

    En af
    eu-de local
    Standard
    null
  • nerModel string kan være null

    The NER model, by id from the ner layer's models in GET /v1/access. Leave it out, or send null, for the default model. An unknown id answers 400 ner_model_unknown, and a retired one or one that does not run at the place you name 400 ner_model_unavailable; a preview model needs your organisation's Redact preview, which an organisation integration key does not have (403 ner_model_preview_required). POST /v1/redact/detect, and the text operations without detectors, run only the default model (400 ner_model_unavailable for another). A model that is not set up at the default place on this server answers 503 ner_model_unconfigured; NER never runs another model. Needs ner in detectors (400 ner_model_without_ner). The response names the model in configuration.nerModel (nerModel on POST /v1/redact/detect).

    Standard
    null
  • model string kan være null

    The language model for llm, by id from GET /v1/access: the models of the llm layer for the processing you choose. Leave it out, or send null, for the default model there. Only models validated for Redact at that processing are accepted (400 llm_model_not_validated): qwen3.8-27b-q8 for local and mistral-small-3.2-24b-instruct-2506 for eu-cloud. GET /v1/access also lists models with reason not_validated, which cannot be chosen. A local model that local infrastructure does not offer right now answers 503 local_model_unavailable, and an EU model your organisation's EU route does not have answers 409 model_not_enabled. Without model, the default must be validated too: on local the server's default model, on eu-cloud the EU model the person behind a personal key saved, else the model on your organisation's EU route (409 llm_model_not_validated). The API never picks another model. Needs llm in detectors and engine pipeline (400 llm_model_not_applicable). configuration.llmModel names the model that ran.

    Standard
    null
  • include string[]

    Extra reports. Each contains originals: protect the response as personal information. mapping: label to original, for POST /v1/redact/restore. changes: exact positions in your text and in redacted. findings: everything the layers found. skipped: CPR-shaped numbers the regex layer left in redacted because their digits do not decode to a plausible birth date, with the reason. A skipped number can still identify a person, for example an erstatningspersonnummer with day + 60. skipped is filled only when regex runs.

    Standard
    []
    Elementer
    højst 4
    Unikke elementer
    Hvert element er en af
    mapping findings changes skipped
  • policy string

    Always all-detected: everything found is replaced, under your organisation's redaction and allow rules.

    En af
    all-detected
    Standard
    all-detected
  • engine string Forhåndsversion

    Preview. Leave out. pipeline (default) runs the chosen detectors. agentic is an experimental method for organisations whose administrator has turned on the Redact Agentic preview (403 agentic_preview_not_enabled otherwise); an organisation integration key gets 403 integration_not_permitted. It needs processing local and detectors regex and llm, with optional ner. It reads the text in windows, so it takes the operation's own text limit; a long document belongs in a text job.

    En af
    pipeline agentic
    Standard
    pipeline
  • sources string[] Forhåndsversion

    Preview. Leave out. Lookup sources for engine agentic, chosen for each call. Each needs the administrator's approval and configured access; an unapproved or unavailable source refuses the call (403 agentic_lookup_not_allowed or 503 agentic_lookup_unavailable) and is never silently dropped. Default none.

    Standard
    []
    Elementer
    højst 5
    Unikke elementer
    Hvert element er en af
    cvr-official bbr web dar wikidata-local

Svar

202 Accepted

The job is accepted. Location points to its status; poll it, then read the result.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Location string

    The job's status: /v1/redact/jobs/{id}.

Body

  • id string påkrævet
    Format
    uuid
  • state string påkrævet
    En af
    queued running succeeded failed cancelled invalidated
  • createdAt string påkrævet
    Format
    date-time
  • expiresAt string påkrævet

    Application retention deadline. A queued job expires this long after it was submitted; a running job is kept for as long as its worker is alive; when the job ends, the retention period counts from the end. Results remain encrypted until explicit deletion or expiry; reads do not consume them.

    Format
    date-time
  • progress object påkrævet
    Underfelter (2)
    • completed integer påkrævet
      Værdi
      mindst 0
    • total integer påkrævet
      Værdi
      mindst 0
  • error string
  • reused boolean
400 Bad Request

The request was refused before processing.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Fejlkoder

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.
  • invalid_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Fejlkoder

  • insufficient_scope The key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.
  • identity_retired The person behind a personal key has been removed from komplai.
  • approved_redact_storage_policy_required Your organisation processes personal data but has no approved storage policy for text jobs.
  • processing_access_withdrawn Access to the job was withdrawn after it was created: the agreement, the processing setup, the organisation's redaction rules or the storage policy for text jobs changed. The job is invalidated and its text and result are deleted. This is final: stop reading the job and do not reuse its Idempotency-Key; submit the text again as a new job when access allows it.
  • processing_choice_not_allowed The organisation does not allow this processing (local infrastructure or EU cloud) through the API, or the connection is not made available through the API.
  • processing_not_enabled The processing is not enabled for the app in the organisation: EU processing is not approved and enabled, or the agreement keeps processing on local infrastructure.
  • processing_not_approved The organisation's processing approval for the app is missing or was withdrawn.
  • app_not_assigned The key's person lost the app or their membership while the request was admitted.
  • ner_model_preview_required The NER model in nerModel is a preview. It needs your organisation's Redact preview, which an organisation integration key does not have.
  • integration_not_permitted An organisation integration key cannot use this operation or this option.
  • agentic_preview_not_enabled The organisation's administrator has not turned on the Redact Agentic preview.
  • agentic_lookup_not_allowed A source in sources is not approved by the organisation's administrator.
  • processing_access_changed The organisation's processing setup changed while the request was handled. Send it again.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
409 Conflict

Conflict with the current state.

Fejlkoder

  • idempotency_conflict This Idempotency-Key was used with a different body. Use a new UUID for a new job.
  • processing_access_changed The organisation's processing setup changed while the request was handled. Send it again.
  • model_not_enabled The model is not one you may use at this processing, or it is not offered there right now.
  • llm_model_not_validated The language model in model is not validated for Redact at the processing you chose. GET /v1/access lists the models you may name.
  • reasoning_effort_not_supported The reasoning effort komplai set for this EU language model in Redact is not one the model accepts on your organisation's EU route. Nothing was sent to the model, and the API does not send another effort.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
413 Content Too Large

Too large.

Fejlkoder

  • text_too_large text is over the operation's limit in UTF-16 code units, or the body is over its byte limit.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
415 Unsupported Media Type

The body has no Content-Type, or one the API does not read, such as XML or form data. Send application/json.

Fejlkoder

  • invalid_body The body is not a JSON object with the documented fields: invalid JSON, Content-Type text/plain, an unknown field, a field of the wrong type, or a required field that is missing or blank.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Fejlkoder

  • rate_limited Too many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer påkrævet

    Seconds to wait before trying again (at most 60).

    Værdi
    1 til 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

503 Service Unavailable

Processing is not available right now.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
KaldPOST /v1/redact/jobs
curl
curl https://api.komplai.dk/v1/redact/jobs \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "text": "Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid.",
    "detectors": ["regex", "ner"],
    "include": ["mapping", "changes"]
  }'
PowerShell
$headers = @{
    Authorization = "Bearer $env:KOMPLAI_TOKEN"
}
$body = [ordered]@{
    text = 'Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid.'
    detectors = @('regex', 'ner')
    include = @('mapping', 'changes')
} | ConvertTo-Json -Depth 100

$request = @{
    Method = 'Post'
    Uri = 'https://api.komplai.dk/v1/redact/jobs'
    Headers = $headers
    ContentType = 'application/json; charset=utf-8'
    Body = $body
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100
Python
import os

import requests

response = requests.post(
    "https://api.komplai.dk/v1/redact/jobs",
    headers={
        "Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
    },
    json={
        "text": "Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid.",
        "detectors": ["regex", "ner"],
        "include": ["mapping", "changes"],
    },
    timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())
JavaScript
const response = await fetch("https://api.komplai.dk/v1/redact/jobs", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    text: "Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid.",
    detectors: ["regex", "ner"],
    include: ["mapping", "changes"],
  }),
});

console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.komplai.dk/v1/redact/jobs");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));
request.Content = new StringContent(@"{
  ""text"": ""Borgeren Mette Kjærgaard Holm, cpr-nr. 120385-1234, bor på Fiktivvej 12, 8000 Aarhus C. Hun kan kontaktes på 21 34 56 78 eller mette.holm@example.invalid."",
  ""detectors"": [""regex"", ""ner""],
  ""include"": [""mapping"", ""changes""]
}", Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
    Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());

Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.

Svar
202 Accepted
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "queued",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 0
  },
  "reused": false
}
202 Accepted
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "succeeded",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 1,
    "total": 1
  },
  "reused": true
}
400 Bad Request
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "insufficient_scope",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/insufficient_scope"
}
409 Conflict
{
  "error": "idempotency_conflict",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/idempotency_conflict"
}
413 Content Too Large
{
  "error": "text_too_large",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/text_too_large"
}
415 Unsupported Media Type
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
429 Too Many Requests
{
  "error": "rate_limited",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/rate_limited"
}
503 Service Unavailable
{
  "error": "redact_jobs_not_enabled",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/redact_jobs_not_enabled"
}

Read the status of a text job

GET /v1/redact/jobs/{id}

state is queued, running, succeeded, failed, cancelled or invalidated. Read the result once it is succeeded. A failed, cancelled or invalidated job is final and carries error with the reason. Wait at least 2 seconds between reads: each read counts against the request limit.

Scopes
redact:process
Prøv kaldet

Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.

En nøgle, der starter med kp_org_ eller kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.

Parametre

Stiparametre

  • id string påkrævet

    The job's id from POST /v1/redact/jobs.

    Format
    uuid

Svar

200 OK

The job's status. A failed, cancelled or invalidated job carries error, for example redact_job_cancelled, processing_access_withdrawn, processing_outcome_uncertain, redact_job_attempts_exhausted, redact_job_stalled, redact_job_progress_failed, engine_retired, model_stalled, model_queue_expired, context_limit, agent_no_progress, rate_limited, ai_credit_exhausted, person_ai_credit_exhausted, redact_job_integrity_failed, incomplete_detection, invalid_detection, detection_service_unavailable, result_too_large, processing_complexity_exceeded, redact_runtime_unavailable, ner_location_unavailable, ner_model_unknown, ner_model_unavailable, ner_model_preview_required, ner_model_unconfigured, llm_model_not_validated, local_model_unavailable, reasoning_effort_not_supported, processing_choice_not_allowed, redact_job_failed. When access to the job was withdrawn, the read answers 403 processing_access_withdrawn instead; that is final too.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid

Body

  • id string påkrævet
    Format
    uuid
  • state string påkrævet
    En af
    queued running succeeded failed cancelled invalidated
  • createdAt string påkrævet
    Format
    date-time
  • expiresAt string påkrævet

    Application retention deadline. A queued job expires this long after it was submitted; a running job is kept for as long as its worker is alive; when the job ends, the retention period counts from the end. Results remain encrypted until explicit deletion or expiry; reads do not consume them.

    Format
    date-time
  • progress object påkrævet
    Underfelter (2)
    • completed integer påkrævet
      Værdi
      mindst 0
    • total integer påkrævet
      Værdi
      mindst 0
  • error string
  • reused boolean
400 Bad Request

The request was refused before processing.

Fejlkoder

  • Bad Request Fastify's reason phrase: a path parameter does not have the documented form, for example a job id that is not a UUID.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Fejlkoder

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.
  • invalid_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Fejlkoder

  • insufficient_scope The key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.
  • identity_retired The person behind a personal key has been removed from komplai.
  • processing_access_withdrawn Access to the job was withdrawn after it was created: the agreement, the processing setup, the organisation's redaction rules or the storage policy for text jobs changed. The job is invalidated and its text and result are deleted. This is final: stop reading the job and do not reuse its Idempotency-Key; submit the text again as a new job when access allows it.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
404 Not Found

Not found.

Fejlkoder

  • not_found No job with this id for this key. A job is visible only to the key that created it, and it disappears when it expires.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Fejlkoder

  • rate_limited Too many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer påkrævet

    Seconds to wait before trying again (at most 60).

    Værdi
    1 til 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

503 Service Unavailable

Processing is not available right now.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
KaldGET /v1/redact/jobs/{id}
curl
curl https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c \
  -H "Authorization: Bearer $KOMPLAI_TOKEN"
PowerShell
$headers = @{
    Authorization = "Bearer $env:KOMPLAI_TOKEN"
}

$request = @{
    Method = 'Get'
    Uri = 'https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c'
    Headers = $headers
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100
Python
import os

import requests

response = requests.get(
    "https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
    headers={
        "Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
    },
    timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())
JavaScript
const response = await fetch("https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c", {
  headers: {
    Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
  },
});

console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
    Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());

Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.

Svar
200 OK
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "queued",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 0
  }
}
200 OK
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "running",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 1
  }
}
200 OK
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "succeeded",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 1,
    "total": 1
  }
}
200 OK
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "failed",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 1
  },
  "error": "detection_service_unavailable"
}
200 OK
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "invalidated",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 1
  },
  "error": "redact_job_attempts_exhausted"
}
400 Bad Request
{
  "error": "Bad Request",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/bad-request"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "insufficient_scope",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/insufficient_scope"
}
404 Not Found
{
  "error": "not_found",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/not_found"
}
429 Too Many Requests
{
  "error": "rate_limited",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/rate_limited"
}
503 Service Unavailable
{
  "error": "redact_job_service_unavailable",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/redact_job_service_unavailable"
}

Delete a text job

DELETE /v1/redact/jobs/{id}

Cancels the job if it is still queued or running and deletes its encrypted text and result at once. Cancellation is final. Only the encrypted replay fingerprint for Idempotency-Key remains until the original expiry. Deleting a job that is already cancelled answers the same 200. Send no body. Deleting does not count against the request limit.

Scopes
redact:process
Prøv kaldet

Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.

En nøgle, der starter med kp_org_ eller kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.

Parametre

Stiparametre

  • id string påkrævet

    The job's id from POST /v1/redact/jobs.

    Format
    uuid

Svar

200 OK

The job is cancelled and its text and result are deleted.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid

Body

  • id string påkrævet
    Format
    uuid
  • state string påkrævet
    En af
    queued running succeeded failed cancelled invalidated
  • createdAt string påkrævet
    Format
    date-time
  • expiresAt string påkrævet

    Application retention deadline. A queued job expires this long after it was submitted; a running job is kept for as long as its worker is alive; when the job ends, the retention period counts from the end. Results remain encrypted until explicit deletion or expiry; reads do not consume them.

    Format
    date-time
  • progress object påkrævet
    Underfelter (2)
    • completed integer påkrævet
      Værdi
      mindst 0
    • total integer påkrævet
      Værdi
      mindst 0
  • error string
  • reused boolean
400 Bad Request

The request was refused before processing.

Fejlkoder

  • invalid_input The request is not what the operation documents, for example invalid JSON, a field that is not listed or a value out of range.
  • Bad Request Fastify's reason phrase: a path parameter does not have the documented form, for example a job id that is not a UUID.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Fejlkoder

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.
  • invalid_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Fejlkoder

  • insufficient_scope The key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.
  • identity_retired The person behind a personal key has been removed from komplai.
  • processing_access_withdrawn Access to the job was withdrawn after it was created: the agreement, the processing setup, the organisation's redaction rules or the storage policy for text jobs changed. The job is invalidated and its text and result are deleted. This is final: stop reading the job and do not reuse its Idempotency-Key; submit the text again as a new job when access allows it.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
404 Not Found

Not found.

Fejlkoder

  • not_found No job with this id for this key. A job is visible only to the key that created it, and it disappears when it expires.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Fejlkoder

  • rate_limited Too many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer påkrævet

    Seconds to wait before trying again (at most 60).

    Værdi
    1 til 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

503 Service Unavailable

Processing is not available right now.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
KaldDELETE /v1/redact/jobs/{id}
curl
curl -X DELETE https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c \
  -H "Authorization: Bearer $KOMPLAI_TOKEN"
PowerShell
$headers = @{
    Authorization = "Bearer $env:KOMPLAI_TOKEN"
}

$request = @{
    Method = 'Delete'
    Uri = 'https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c'
    Headers = $headers
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100
Python
import os

import requests

response = requests.delete(
    "https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
    headers={
        "Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
    },
    timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())
JavaScript
const response = await fetch("https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
  },
});

console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Delete, "https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
    Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());

Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.

Svar
200 OK
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "cancelled",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 1
  },
  "error": "redact_job_cancelled"
}
400 Bad Request
{
  "error": "Bad Request",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/bad-request"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "insufficient_scope",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/insufficient_scope"
}
404 Not Found
{
  "error": "not_found",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/not_found"
}
429 Too Many Requests
{
  "error": "rate_limited",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/rate_limited"
}
503 Service Unavailable
{
  "error": "redact_job_service_unavailable",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/redact_job_service_unavailable"
}

Read the result of a text job

GET /v1/redact/jobs/{id}/result

200 with the same result as POST /v1/redact once the job has succeeded. 202 with the job's status while it is queued or running; wait Retry-After seconds. 410 when it failed, was cancelled or was invalidated. Reading does not delete the encrypted result: DELETE removes text and result at once, and expiry removes the job and its replay fingerprint.

Scopes
redact:process
Prøv kaldet

Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.

En nøgle, der starter med kp_org_ eller kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.

Parametre

Stiparametre

  • id string påkrævet

    The job's id from POST /v1/redact/jobs.

    Format
    uuid

Svar

200 OK

The job's result, the same as POST /v1/redact returns for its body. Reading it does not delete it.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid

Body

  • engine string påkrævet
    En af
    pipeline agentic
  • redacted string påkrævet

    The pseudonymised text, with labels such as [PERSON-1]. The same original gets the same label throughout the text.

  • mode string påkrævet
    En af
    regex ner semantic
  • processing string påkrævet

    Where the language model ran, or would have run.

    En af
    local eu-cloud
  • policy string påkrævet
    En af
    all-detected
  • policyVersion string påkrævet
    En af
    redact-text-v1
  • offsetEncoding string påkrævet

    Every offset counts UTF-16 code units.

    En af
    utf-16
  • charsIn integer påkrævet

    Length of your text in UTF-16 code units.

    Værdi
    1 til 2.000.000
  • charsOut integer påkrævet

    Length of redacted in UTF-16 code units.

    Værdi
    mindst 0
  • truncated boolean påkrævet

    Always false: a truncated detection fails the call instead.

    En af
    false
  • degraded boolean påkrævet

    Always false: a degraded detection fails the call instead.

    En af
    false
  • configuration object

    The choices that took effect. llmModel names the language model when it is known, and llmReasoningEffort the reasoning effort it was sent: by the llm layer, and on eu-cloud by mode semantic without detectors too. nerModel and nerDeployment name the NER model and place when you chose them, and nerDeployment also when NER ran at another place than eu-de.

    Underfelter (9)
    • engine string påkrævet
      En af
      pipeline agentic
    • mode string påkrævet
      En af
      regex ner semantic
    • detectors string[] påkrævet
      Hvert element er en af
      regex ner llm
    • sources string[] påkrævet
      Hvert element er en af
      cvr-official bbr web dar wikidata-local
    • processing string påkrævet
      En af
      local eu-cloud
    • nerModel string

      The NER model you named in nerModel.

    • nerDeployment string

      Where NER ran: present when you named the place, or when NER ran somewhere other than eu-de.

      En af
      eu-de local
    • llmModel string

      The language model that answered, when it is known.

    • llmReasoningEffort string

      The reasoning effort the language model was sent: by the llm layer of the pipeline engine, and on eu-cloud by mode semantic without detectors too. komplai sets it per model when it validates the model for Redact; none means no reasoning.

      En af
      none low medium high xhigh max
  • execution object

    What actually ran: detectorsRun lists the layers, and the counts appear when they were measured. A missing count does not mean zero. llmOccurrenceRepairs counts llm findings whose quote occurs once in the text but whose occurrence number pointed past it; each was placed on that one match. llmResolvedFindings counts llm findings whose quote could not be placed exactly and that were placed on every span equal to the quote once spacing and line breaks, invisible characters, typographic quotes and dashes, and for quotes of two or more words or with a digit, letter case are ignored; each is an exact span of the text. llmWindows counts the language model's answers the result is made of. llmSplits counts answers that could not be used and were discarded; each made two more calls, one for each half of its part of the text.

    Underfelter (13)
    • completed boolean påkrævet
      En af
      true
    • detectorsRun string[] påkrævet
      Hvert element er en af
      regex ner llm
    • detectionPasses integer
      Værdi
      mindst 0
    • nerCalls integer
      Værdi
      mindst 0
    • llmCalls integer
      Værdi
      mindst 0
    • llmOccurrenceRepairs integer
      Værdi
      mindst 0
    • llmResolvedFindings integer
      Værdi
      mindst 0
    • llmWindows integer
      Værdi
      mindst 0
    • llmSplits integer
      Værdi
      mindst 0
    • toolCalls integer
      Værdi
      mindst 0
    • rounds integer
      Værdi
      mindst 0
    • documentCoverageComplete boolean
    • releaseReviewComplete boolean
  • mapping map<string>

    Label to canonical original mention. Use changes for exact source reconstruction.

    Underfelter (1)
    • Vilkårlig nøgle string
  • entries object[]

    Returned with mapping: one entry per label, with its type, original, confidence and source layer.

    Underfelter (5)
    • placeholder string påkrævet
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • value string påkrævet
    • confidence string påkrævet
      En af
      high medium low
    • source string påkrævet

      The layer that found it: regex (the rules), ner, llm (the language model) or custom (your organisation's own redaction rules). Always present.

      En af
      regex ner llm custom
  • findings object[]

    Everything the layers found, with offsets in your text and the layer that found each in source.

    Underfelter (9)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • value string påkrævet
    • confidence string påkrævet
      En af
      high medium low
    • source string påkrævet

      The layer that found it: regex (the rules), ner, llm (the language model) or custom (your organisation's own redaction rules). Always present.

      En af
      regex ner llm custom
    • customLabel string
      Længde
      højst 64
    • replacementToken string
      Længde
      højst 128
    • entityId string
  • changes object[]

    Each replacement with its offsets in your text (start, end) and in redacted (outputStart, outputEnd). Apply them in reverse order of outputStart to rebuild your exact text.

    Underfelter (7)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • outputStart integer påkrævet
      Værdi
      mindst 0
    • outputEnd integer påkrævet
      Værdi
      mindst 1
    • original string påkrævet
    • replacement string påkrævet
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
  • skipped object[]

    CPR-shaped numbers the regex layer declined and no final change covers, with a reason code and an English explanation. They remain in redacted and can still identify a person, for example an erstatningspersonnummer with day + 60 (reported as cpr_invalid_date). Empty when the regex layer did not run (NER- or LLM-only detectors, or engine agentic).

    Underfelter (6)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • value string påkrævet
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • reason string påkrævet
      En af
      cpr_unknown_century cpr_birth_year_out_of_range cpr_invalid_date
    • detail string påkrævet
      Længde
      højst 200
202 Accepted

The job is still queued or running. The body is its status.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer

    Seconds to wait before reading again.

    En af
    2

Body

  • id string påkrævet
    Format
    uuid
  • state string påkrævet
    En af
    queued running succeeded failed cancelled invalidated
  • createdAt string påkrævet
    Format
    date-time
  • expiresAt string påkrævet

    Application retention deadline. A queued job expires this long after it was submitted; a running job is kept for as long as its worker is alive; when the job ends, the retention period counts from the end. Results remain encrypted until explicit deletion or expiry; reads do not consume them.

    Format
    date-time
  • progress object påkrævet
    Underfelter (2)
    • completed integer påkrævet
      Værdi
      mindst 0
    • total integer påkrævet
      Værdi
      mindst 0
  • error string
  • reused boolean
400 Bad Request

The request was refused before processing.

Fejlkoder

  • Bad Request Fastify's reason phrase: a path parameter does not have the documented form, for example a job id that is not a UUID.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Fejlkoder

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.
  • invalid_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Fejlkoder

  • insufficient_scope The key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.
  • identity_retired The person behind a personal key has been removed from komplai.
  • processing_access_withdrawn Access to the job was withdrawn after it was created: the agreement, the processing setup, the organisation's redaction rules or the storage policy for text jobs changed. The job is invalidated and its text and result are deleted. This is final: stop reading the job and do not reuse its Idempotency-Key; submit the text again as a new job when access allows it.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
404 Not Found

Not found.

Fejlkoder

  • not_found No job with this id for this key. A job is visible only to the key that created it, and it disappears when it expires.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
410 Gone

The job ended without a result. error is the job's code (see GET /v1/redact/jobs/{id}) and state its state.

Fejlkoder

  • redact_job_cancelled The job was deleted or cancelled.
  • redact_job_failed The job failed for a reason that is not passed on, for example a reached monthly AI spending cap or a failing EU cloud model.
  • redact_job_attempts_exhausted The text job was interrupted three times, for example by restarts, and was stopped. No partial result is kept.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Fejlkoder

  • rate_limited Too many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer påkrævet

    Seconds to wait before trying again (at most 60).

    Værdi
    1 til 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

503 Service Unavailable

Processing is not available right now.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
KaldGET /v1/redact/jobs/{id}/result
curl
curl https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c/result \
  -H "Authorization: Bearer $KOMPLAI_TOKEN"
PowerShell
$headers = @{
    Authorization = "Bearer $env:KOMPLAI_TOKEN"
}

$request = @{
    Method = 'Get'
    Uri = 'https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c/result'
    Headers = $headers
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100
Python
import os

import requests

response = requests.get(
    "https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c/result",
    headers={
        "Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
    },
    timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())
JavaScript
const response = await fetch("https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c/result", {
  headers: {
    Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
  },
});

console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.komplai.dk/v1/redact/jobs/3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c/result");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
    Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());

Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.

Svar
200 OK
{
  "redacted": "Borgeren [PERSON-1], cpr-nr. [CPR-1], bor på [ADRESSE-1]. Hun kan kontaktes på [TLF-1] eller [EMAIL-1].",
  "engine": "pipeline",
  "mode": "ner",
  "processing": "local",
  "policy": "all-detected",
  "policyVersion": "redact-text-v1",
  "offsetEncoding": "utf-16",
  "charsIn": 154,
  "charsOut": 103,
  "truncated": false,
  "degraded": false,
  "configuration": {
    "engine": "pipeline",
    "mode": "ner",
    "detectors": ["regex", "ner"],
    "sources": [],
    "processing": "local"
  },
  "execution": {
    "completed": true,
    "detectorsRun": ["regex", "ner"],
    "detectionPasses": 1,
    "nerCalls": 1,
    "llmCalls": 0
  },
  "mapping": {
    "[PERSON-1]": "Mette Kjærgaard Holm",
    "[CPR-1]": "120385-1234",
    "[ADRESSE-1]": "Fiktivvej 12, 8000 Aarhus C",
    "[TLF-1]": "21 34 56 78",
    "[EMAIL-1]": "mette.holm@example.invalid"
  },
  "entries": [
    {
      "placeholder": "[PERSON-1]",
      "type": "person",
      "value": "Mette Kjærgaard Holm",
      "confidence": "medium",
      "source": "ner"
    },
    {
      "placeholder": "[CPR-1]",
      "type": "cpr",
      "value": "120385-1234",
      "confidence": "high",
      "source": "regex"
    },
    {
      "placeholder": "[ADRESSE-1]",
      "type": "address",
      "value": "Fiktivvej 12, 8000 Aarhus C",
      "confidence": "high",
      "source": "ner"
    },
    {
      "placeholder": "[TLF-1]",
      "type": "phone",
      "value": "21 34 56 78",
      "confidence": "medium",
      "source": "regex"
    },
    {
      "placeholder": "[EMAIL-1]",
      "type": "email",
      "value": "mette.holm@example.invalid",
      "confidence": "high",
      "source": "regex"
    }
  ],
  "changes": [
    {
      "start": 9,
      "end": 29,
      "outputStart": 9,
      "outputEnd": 19,
      "original": "Mette Kjærgaard Holm",
      "replacement": "[PERSON-1]",
      "type": "person"
    },
    {
      "start": 39,
      "end": 50,
      "outputStart": 29,
      "outputEnd": 36,
      "original": "120385-1234",
      "replacement": "[CPR-1]",
      "type": "cpr"
    },
    {
      "start": 59,
      "end": 86,
      "outputStart": 45,
      "outputEnd": 56,
      "original": "Fiktivvej 12, 8000 Aarhus C",
      "replacement": "[ADRESSE-1]",
      "type": "address"
    },
    {
      "start": 109,
      "end": 120,
      "outputStart": 79,
      "outputEnd": 86,
      "original": "21 34 56 78",
      "replacement": "[TLF-1]",
      "type": "phone"
    },
    {
      "start": 127,
      "end": 153,
      "outputStart": 93,
      "outputEnd": 102,
      "original": "mette.holm@example.invalid",
      "replacement": "[EMAIL-1]",
      "type": "email"
    }
  ]
}
202 Accepted
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "running",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 1
  }
}
400 Bad Request
{
  "error": "Bad Request",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/bad-request"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "insufficient_scope",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/insufficient_scope"
}
404 Not Found
{
  "error": "not_found",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/not_found"
}
410 Gone
{
  "error": "redact_job_cancelled",
  "state": "cancelled",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/redact_job_cancelled"
}
429 Too Many Requests
{
  "error": "rate_limited",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/rate_limited"
}
503 Service Unavailable
{
  "error": "redact_job_integrity_failed",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/redact_job_integrity_failed"
}

Pseudonymise the text of a PDF or Word file (beta) Beta

POST /v1/redact/file

Beta. Send a PDF with a text layer or a Word .docx as base64 in JSON; komplai extracts its text and runs the same Redact processing as for text, with the same options. The response is pseudonymised text, not a redacted file. No OCR runs: a scanned page is refused (422 scanned_pages_not_supported, with the page numbers) unless allowPagesWithoutText is true. The text is extracted on komplai's API servers (EU · Germany) in memory; the file is not stored. File problems: 400 unsupported_file_type, file_type_mismatch, invalid_file_encoding, empty_file; 413 file_too_large, too_many_pages, text_too_large, file_too_complex; 422 invalid_file, encrypted_file, no_text_found, scanned_pages_not_supported; 429 processing_capacity_busy while other files are being read. No method guarantees anonymity; check the result. At most 750,000 UTF-16 code units of extracted text, and work that finishes within 300 seconds: a run whose estimate exceeds that is refused with 413 use_job and its estimate before anything is processed, and one the estimate cannot cover (an EU language model, a wait in the shared queue) can still end with 504 processing_timeout, as on POST /v1/redact. Longer files go to POST /v1/redact/file/jobs, or send this call with Prefer: respond-async to get 202 and a job. pages gives each page's offsets in the extracted text and in redacted. Agentic processing has the same requirements as on POST /v1/redact.

Organisation integration keys cannot use engine agentic: 403 integration_not_permitted.

Scopes
redact:process
Prøv kaldet

Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.

En nøgle, der starter med kp_org_ eller kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.

Parametre

Headere

  • prefer string

    Optional. respond-async answers 202 with a text job, exactly as POST /v1/redact/file/jobs, instead of holding the connection. Without it the call never becomes a job.

    En af
    respond-async
  • idempotency-key string

    Optional. A new UUID for each job, in upper or lower case. If the connection drops, send the same request again with the same key: within the job's lifetime the same key and body return the same job (reused true) instead of a second one, and the same key with another body answers 409 idempotency_conflict. Never reuse a key for another text. The key is bound to your organisation, the owner (person or integration) and the API key. The default {{$guid}} is Postman's variable for a new UUID on each request; in other tools, generate a UUID for each job or leave the header out.

    Standard
    {{$guid}}
    Format
    uuid

Body i kaldet

  • file object påkrævet
    Underfelter (3)
    • filename string påkrævet

      The file's name. Its extension (.pdf or .docx) must match the content. Used only to check the type; not stored, logged or returned.

      Længde
      1 til 255
    • contentType string

      Optional. Must agree with the content when it names PDF or Word.

      En af
      application/pdf application/vnd.openxmlformats-officedocument.wordprocessingml.document application/octet-stream
      Standard
      application/octet-stream
    • data string påkrævet

      The file's bytes, base64 encoded (standard or URL-safe; line breaks are ignored). At most 50 MiB decoded and 2,000 PDF pages. PDF needs a text layer; Word .docx only, not .doc.

      Format
      byte
  • detectors string[]

    The layers to run, in any non-empty combination. regex: rules for CPR numbers, phone numbers, e-mail addresses and more. ner: a model for names, organisations and addresses. llm: a language model for what rules and NER miss, such as health data in free text; it can take up to a minute. It reads the text in parts of at most 12,000 characters. When its answer for a part cannot be used, that answer is discarded and the part is asked again in two overlapping halves, down to halves of 1,500 characters: at most 14 extra calls for a part. If an answer still cannot be used, the call fails with 502 invalid_detection or incomplete_detection and returns no result. Default regex and ner. The older field mode is still accepted but is not listed here: leave it out, because if you send both, they must agree (400 unsupported_engine_mode). engine agentic needs regex and llm, with optional ner.

    Standard
    ["regex", "ner"]
    Elementer
    1 til 3
    Unikke elementer
    Hvert element er en af
    regex ner llm
  • processing string

    Where the language model (llm) runs. local (default): komplai's local infrastructure in Denmark, with no AI charge. eu-cloud: komplai's EU cloud, which answers faster. It needs llm in detectors and EU processing approved for your organisation, and its usage counts towards the organisation's monthly AI spending cap (429 ai_credit_exhausted when the cap is reached). Every call to the model, including a part asked again in halves, is checked against the cap and counted on its own. Name the model in model, or leave it out for the default model there. Rules always run on komplai's servers in Germany (EU), and NER at the place in nerDeployment or, without one, at the default place GET /v1/access marks. GET /v1/access names where each layer processes text for your organisation, including eu-cloud, in services[].hosting.processing.layers. The API never switches between local and eu-cloud by itself.

    En af
    local eu-cloud
    Standard
    local
  • nerDeployment string kan være null

    Where the ner layer runs: eu-de (komplai's servers in Germany, EU) or local (komplai's local infrastructure in Denmark). Leave it out, or send null, for the default place: the one GET /v1/access marks with default true in the ner layer's places (services[].hosting.processing.layers), eu-de unless komplai has changed it. Each place there has available and a reason for the operations with detectors, and detect with the same for POST /v1/redact/detect and the operations without detectors, so check that the place you name is available for the operation you call. A place that cannot be used now answers 503 ner_location_unavailable and names the place in nerDeployment; NER never moves to another place. Needs ner in detectors (400 ner_deployment_without_ner); any other value answers 400 invalid_ner_deployment. The response names the place in configuration.nerDeployment (nerDeployment on POST /v1/redact/detect).

    En af
    eu-de local
    Standard
    null
  • nerModel string kan være null

    The NER model, by id from the ner layer's models in GET /v1/access. Leave it out, or send null, for the default model. An unknown id answers 400 ner_model_unknown, and a retired one or one that does not run at the place you name 400 ner_model_unavailable; a preview model needs your organisation's Redact preview, which an organisation integration key does not have (403 ner_model_preview_required). POST /v1/redact/detect, and the text operations without detectors, run only the default model (400 ner_model_unavailable for another). A model that is not set up at the default place on this server answers 503 ner_model_unconfigured; NER never runs another model. Needs ner in detectors (400 ner_model_without_ner). The response names the model in configuration.nerModel (nerModel on POST /v1/redact/detect).

    Standard
    null
  • model string kan være null

    The language model for llm, by id from GET /v1/access: the models of the llm layer for the processing you choose. Leave it out, or send null, for the default model there. Only models validated for Redact at that processing are accepted (400 llm_model_not_validated): qwen3.8-27b-q8 for local and mistral-small-3.2-24b-instruct-2506 for eu-cloud. GET /v1/access also lists models with reason not_validated, which cannot be chosen. A local model that local infrastructure does not offer right now answers 503 local_model_unavailable, and an EU model your organisation's EU route does not have answers 409 model_not_enabled. Without model, the default must be validated too: on local the server's default model, on eu-cloud the EU model the person behind a personal key saved, else the model on your organisation's EU route (409 llm_model_not_validated). The API never picks another model. Needs llm in detectors and engine pipeline (400 llm_model_not_applicable). configuration.llmModel names the model that ran.

    Standard
    null
  • policy string

    Always all-detected: everything found is replaced, under your organisation's redaction and allow rules.

    En af
    all-detected
    Standard
    all-detected
  • engine string Forhåndsversion

    Preview. Leave out. pipeline (default) runs the chosen detectors. agentic is an experimental method for organisations whose administrator has turned on the Redact Agentic preview (403 agentic_preview_not_enabled otherwise); an organisation integration key gets 403 integration_not_permitted. It needs processing local and detectors regex and llm, with optional ner. It reads the text in windows, so it takes the operation's own text limit; a long document belongs in a text job.

    En af
    pipeline agentic
    Standard
    pipeline
  • sources string[] Forhåndsversion

    Preview. Leave out. Lookup sources for engine agentic, chosen for each call. Each needs the administrator's approval and configured access; an unapproved or unavailable source refuses the call (403 agentic_lookup_not_allowed or 503 agentic_lookup_unavailable) and is never silently dropped. Default none.

    Standard
    []
    Elementer
    højst 5
    Unikke elementer
    Hvert element er en af
    cvr-official bbr web dar wikidata-local
  • include string[]

    As POST /v1/redact, plus source: the extracted text the offsets refer to. Every report except the bare result contains originals; protect it as personal information.

    Standard
    []
    Elementer
    højst 5
    Unikke elementer
    Hvert element er en af
    mapping findings changes skipped source
  • allowPagesWithoutText boolean

    A PDF page without a text layer (a scan, an image or a blank page) refuses the file with scanned_pages_not_supported, because no OCR runs. true processes the other pages and reports those pages with hasText false.

    Standard
    false

Svar

200 OK

The pseudonymised text of the file, with each page's offsets in the extracted text and in redacted.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid

Body

  • engine string påkrævet
    En af
    pipeline agentic
  • redacted string påkrævet

    The pseudonymised text, with labels such as [PERSON-1]. The same original gets the same label throughout the text.

  • mode string påkrævet
    En af
    regex ner semantic
  • processing string påkrævet

    Where the language model ran, or would have run.

    En af
    local eu-cloud
  • policy string påkrævet
    En af
    all-detected
  • policyVersion string påkrævet
    En af
    redact-text-v1
  • offsetEncoding string påkrævet

    Every offset counts UTF-16 code units.

    En af
    utf-16
  • charsIn integer påkrævet

    Length of your text in UTF-16 code units.

    Værdi
    1 til 2.000.000
  • charsOut integer påkrævet

    Length of redacted in UTF-16 code units.

    Værdi
    mindst 0
  • truncated boolean påkrævet

    Always false: a truncated detection fails the call instead.

    En af
    false
  • degraded boolean påkrævet

    Always false: a degraded detection fails the call instead.

    En af
    false
  • configuration object

    The choices that took effect. llmModel names the language model when it is known, and llmReasoningEffort the reasoning effort it was sent: by the llm layer, and on eu-cloud by mode semantic without detectors too. nerModel and nerDeployment name the NER model and place when you chose them, and nerDeployment also when NER ran at another place than eu-de.

    Underfelter (9)
    • engine string påkrævet
      En af
      pipeline agentic
    • mode string påkrævet
      En af
      regex ner semantic
    • detectors string[] påkrævet
      Hvert element er en af
      regex ner llm
    • sources string[] påkrævet
      Hvert element er en af
      cvr-official bbr web dar wikidata-local
    • processing string påkrævet
      En af
      local eu-cloud
    • nerModel string

      The NER model you named in nerModel.

    • nerDeployment string

      Where NER ran: present when you named the place, or when NER ran somewhere other than eu-de.

      En af
      eu-de local
    • llmModel string

      The language model that answered, when it is known.

    • llmReasoningEffort string

      The reasoning effort the language model was sent: by the llm layer of the pipeline engine, and on eu-cloud by mode semantic without detectors too. komplai sets it per model when it validates the model for Redact; none means no reasoning.

      En af
      none low medium high xhigh max
  • execution object

    What actually ran: detectorsRun lists the layers, and the counts appear when they were measured. A missing count does not mean zero. llmOccurrenceRepairs counts llm findings whose quote occurs once in the text but whose occurrence number pointed past it; each was placed on that one match. llmResolvedFindings counts llm findings whose quote could not be placed exactly and that were placed on every span equal to the quote once spacing and line breaks, invisible characters, typographic quotes and dashes, and for quotes of two or more words or with a digit, letter case are ignored; each is an exact span of the text. llmWindows counts the language model's answers the result is made of. llmSplits counts answers that could not be used and were discarded; each made two more calls, one for each half of its part of the text.

    Underfelter (13)
    • completed boolean påkrævet
      En af
      true
    • detectorsRun string[] påkrævet
      Hvert element er en af
      regex ner llm
    • detectionPasses integer
      Værdi
      mindst 0
    • nerCalls integer
      Værdi
      mindst 0
    • llmCalls integer
      Værdi
      mindst 0
    • llmOccurrenceRepairs integer
      Værdi
      mindst 0
    • llmResolvedFindings integer
      Værdi
      mindst 0
    • llmWindows integer
      Værdi
      mindst 0
    • llmSplits integer
      Værdi
      mindst 0
    • toolCalls integer
      Værdi
      mindst 0
    • rounds integer
      Værdi
      mindst 0
    • documentCoverageComplete boolean
    • releaseReviewComplete boolean
  • mapping map<string>

    Label to canonical original mention. Use changes for exact source reconstruction.

    Underfelter (1)
    • Vilkårlig nøgle string
  • entries object[]

    Returned with mapping: one entry per label, with its type, original, confidence and source layer.

    Underfelter (5)
    • placeholder string påkrævet
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • value string påkrævet
    • confidence string påkrævet
      En af
      high medium low
    • source string påkrævet

      The layer that found it: regex (the rules), ner, llm (the language model) or custom (your organisation's own redaction rules). Always present.

      En af
      regex ner llm custom
  • findings object[]

    Everything the layers found, with offsets in your text and the layer that found each in source.

    Underfelter (9)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • value string påkrævet
    • confidence string påkrævet
      En af
      high medium low
    • source string påkrævet

      The layer that found it: regex (the rules), ner, llm (the language model) or custom (your organisation's own redaction rules). Always present.

      En af
      regex ner llm custom
    • customLabel string
      Længde
      højst 64
    • replacementToken string
      Længde
      højst 128
    • entityId string
  • changes object[]

    Each replacement with its offsets in your text (start, end) and in redacted (outputStart, outputEnd). Apply them in reverse order of outputStart to rebuild your exact text.

    Underfelter (7)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • outputStart integer påkrævet
      Værdi
      mindst 0
    • outputEnd integer påkrævet
      Værdi
      mindst 1
    • original string påkrævet
    • replacement string påkrævet
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
  • skipped object[]

    CPR-shaped numbers the regex layer declined and no final change covers, with a reason code and an English explanation. They remain in redacted and can still identify a person, for example an erstatningspersonnummer with day + 60 (reported as cpr_invalid_date). Empty when the regex layer did not run (NER- or LLM-only detectors, or engine agentic).

    Underfelter (6)
    • start integer påkrævet
      Værdi
      mindst 0
    • end integer påkrævet
      Værdi
      mindst 1
    • value string påkrævet
    • type string påkrævet
      En af
      cpr cvr pno phone email iban account person address organisation dob demographic sensitive quasi health criminal social special url creditcard ip jwt passport driverslicense employee_id matrikel bfe ejendomsnummer dgu custom
    • reason string påkrævet
      En af
      cpr_unknown_century cpr_birth_year_out_of_range cpr_invalid_date
    • detail string påkrævet
      Længde
      højst 200
  • file object påkrævet
    Underfelter (3)
    • type string påkrævet
      En af
      pdf docx
    • bytes integer påkrævet
      Værdi
      mindst 1
    • pageCount integer påkrævet
      Værdi
      mindst 1
  • pages object[] påkrævet
    Underfelter (6)
    • number integer påkrævet

      PDF page number. For .docx: body parts split at the page breaks Word recorded, then headers, footers, footnotes and endnotes, one part each.

      Værdi
      mindst 1
    • start integer påkrævet

      Start of the page in the extracted text (the source the other offsets refer to).

      Værdi
      mindst 0
    • end integer påkrævet

      Exclusive end in the extracted text.

      Værdi
      mindst 0
    • hasText boolean påkrævet

      false for a page without a text layer, only with allowPagesWithoutText.

    • redactedStart integer påkrævet

      Start of the page in redacted. A label that spans a page boundary belongs to the earlier page.

      Værdi
      mindst 0
    • redactedEnd integer påkrævet

      Exclusive end in redacted.

      Værdi
      mindst 0
  • source string

    Only with include source: the extracted text, pages separated by a blank line. Contains personal information.

    Længde
    højst 2.000.000
202 Accepted

Only with Prefer: respond-async: the file's text is a job, exactly as POST /v1/redact/file/jobs answers.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Location string

    The job's status: /v1/redact/jobs/{id}.

  • Preference-Applied string

    respond-async

    En af
    respond-async

Body

  • id string påkrævet
    Format
    uuid
  • state string påkrævet
    En af
    queued running succeeded failed cancelled invalidated
  • createdAt string påkrævet
    Format
    date-time
  • expiresAt string påkrævet

    Application retention deadline. A queued job expires this long after it was submitted; a running job is kept for as long as its worker is alive; when the job ends, the retention period counts from the end. Results remain encrypted until explicit deletion or expiry; reads do not consume them.

    Format
    date-time
  • progress object påkrævet
    Underfelter (2)
    • completed integer påkrævet
      Værdi
      mindst 0
    • total integer påkrævet
      Værdi
      mindst 0
  • error string
  • reused boolean
  • file object påkrævet
    Underfelter (3)
    • type string påkrævet
      En af
      pdf docx
    • bytes integer påkrævet
      Værdi
      mindst 1
    • pageCount integer påkrævet
      Værdi
      mindst 1
  • pages object[] påkrævet

    Offsets in the extracted text, which is the job's source. Read the result from GET /v1/redact/jobs/{id}/result; with include changes, its changes map these offsets into redacted.

    Underfelter (4)
    • number integer påkrævet

      PDF page number. For .docx: body parts split at the page breaks Word recorded, then headers, footers, footnotes and endnotes, one part each.

      Værdi
      mindst 1
    • start integer påkrævet

      Start of the page in the extracted text (the source the other offsets refer to).

      Værdi
      mindst 0
    • end integer påkrævet

      Exclusive end in the extracted text.

      Værdi
      mindst 0
    • hasText boolean påkrævet

      false for a page without a text layer, only with allowPagesWithoutText.

  • source string

    Only with include source: the extracted text, pages separated by a blank line. Contains personal information.

    Længde
    højst 2.000.000
400 Bad Request

The request was refused before processing.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Fejlkoder

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.
  • invalid_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Fejlkoder

  • insufficient_scope The key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.
  • identity_retired The person behind a personal key has been removed from komplai.
  • processing_choice_not_allowed The organisation does not allow this processing (local infrastructure or EU cloud) through the API, or the connection is not made available through the API.
  • processing_not_enabled The processing is not enabled for the app in the organisation: EU processing is not approved and enabled, or the agreement keeps processing on local infrastructure.
  • processing_not_approved The organisation's processing approval for the app is missing or was withdrawn.
  • app_not_assigned The key's person lost the app or their membership while the request was admitted.
  • processing_access_changed The organisation's processing setup changed while the request was handled. Send it again.
  • ai_credit_not_granted No monthly AI spending cap is set up for this month, so eu-cloud cannot run.
  • ner_model_preview_required The NER model in nerModel is a preview. It needs your organisation's Redact preview, which an organisation integration key does not have.
  • integration_not_permitted An organisation integration key cannot use this operation or this option.
  • agentic_preview_not_enabled The organisation's administrator has not turned on the Redact Agentic preview.
  • agentic_lookup_not_allowed A source in sources is not approved by the organisation's administrator.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
409 Conflict

Conflict with the current state.

Fejlkoder

  • processing_policy_changed Your organisation's redaction rules changed while the request ran. Send it again.
  • model_not_enabled The model is not one you may use at this processing, or it is not offered there right now.
  • llm_model_not_validated The language model in model is not validated for Redact at the processing you chose. GET /v1/access lists the models you may name.
  • reasoning_effort_not_supported The reasoning effort komplai set for this EU language model in Redact is not one the model accepts on your organisation's EU route. Nothing was sent to the model, and the API does not send another effort.
  • processing_access_changed The organisation's processing setup changed while the request was handled. Send it again.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
413 Content Too Large

Too large.

Fejlkoder

  • file_too_large The file is over 50 MiB, or the body is over its byte limit.
  • too_many_pages The PDF has more than 2,000 pages.
  • file_too_complex Reading the file took more than 120 seconds or more resources than allowed (memory, ZIP entries, XML size or depth).
  • text_too_large text is over the operation's limit in UTF-16 code units, or the body is over its byte limit.
  • use_job The run cannot finish within the 300 seconds a synchronous call may take. estimatedSeconds is komplai's estimate from its measured speeds, with an empty queue; holdSeconds is the limit. Nothing was processed or charged. Send the same body as a text job (POST /v1/redact/jobs), or this call with Prefer: respond-async.
  • processing_complexity_exceeded The text needs more work than its length allows: more candidate matches or matched characters than the per-character bounds in /v1/access, coreference matching work beyond its per-character bound (for example one name nested inside itself thousands of times), or more time for the organisation rules than their limit, which grows with the text and the number of rules. The bounds grow with the text, so splitting it rarely helps. Nothing partial is returned.
  • result_too_large The result would be over 32 MiB. Ask for fewer include reports or split the text.
  • context_limit The input and the requested output do not fit the model: max_tokens is over the model's limit, the input with max_tokens is over its context, or, in Redact, a part of the text does not fit even after it was asked again in halves down to 1,500 characters.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
415 Unsupported Media Type

The body has no Content-Type, or one the API does not read, such as XML or form data. Send application/json.

Fejlkoder

  • invalid_body The body is not a JSON object with the documented fields: invalid JSON, Content-Type text/plain, an unknown field, a field of the wrong type, or a required field that is missing or blank.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
422 Unprocessable Content

The file cannot be read.

Fejlkoder

  • invalid_file file is missing or malformed (filename missing, blank, longer than 255 characters or with control characters; data not a string; an unknown key), or the PDF or Word file itself is damaged or not a Word document.
  • encrypted_file The PDF is password protected.
  • scanned_pages_not_supported A page has no text layer, for example a scan. No OCR runs. pages lists the pages; allowPagesWithoutText true processes the rest.
  • no_text_found The file contains no text at all.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Fejlkoder

  • processing_capacity_busy All organisation-rule workers in this API process are busy. There is no queue: try again after Retry-After.
  • rate_limited Too many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.
  • ai_credit_exhausted The organisation's monthly AI spending cap for EU cloud is reached, or its own lower limit, or on a pilot the pilot's total allowance. Local processing keeps working.
  • person_ai_credit_exhausted Your personal AI limit is reached (personal keys only).

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer påkrævet

    Seconds to wait before trying again (at most 60).

    Værdi
    1 til 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

502 Bad Gateway

A processing service failed. No partial result is returned.

Fejlkoder

  • incomplete_detection A detection layer did not finish the whole text. No partial result is returned.
  • invalid_detection A detection layer returned output that failed validation. For llm: an answer that still could not be used after its part of the text was asked again in halves down to 1,500 characters.
  • detection_service_unavailable The detection service could not be reached or failed.
  • unsafe_placeholder A fixed replacement token from your organisation's rules occurs in the text or collides with a label.
  • service_unavailable The model failed or could not be reached, or local infrastructure is not set up for this call right now.
  • invalid_response The model's answer failed validation, so nothing was returned.
  • agent_no_progress Redact Agentic stopped making progress: several rounds in a row read nothing new, found nothing and moved to no new step. No partial result is returned.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
503 Service Unavailable

Processing is not available right now.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
504 Gateway Timeout

The call timed out.

Fejlkoder

  • processing_timeout The call took more than 300 seconds, or the client disconnected. Send long texts as text jobs.
  • model_stalled The language model stopped answering: its connection was silent, or it ran past the time its answer needs at the model's measured speed. No partial result is returned.
  • model_queue_expired The language model's shared queue on local infrastructure did not reach this call before its deadline. Try again later, or send it as a text job, which waits for its turn.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
KaldPOST /v1/redact/file
curl
curl https://api.komplai.dk/v1/redact/file \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "file": {
      "filename": "afgoerelse.pdf",
      "contentType": "application/pdf",
      "data": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo="
    },
    "detectors": ["regex", "ner"],
    "processing": "local",
    "include": ["mapping"]
  }'
PowerShell
$headers = @{
    Authorization = "Bearer $env:KOMPLAI_TOKEN"
}
$body = [ordered]@{
    file = [ordered]@{
        filename = 'afgoerelse.pdf'
        contentType = 'application/pdf'
        data = 'JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo='
    }
    detectors = @('regex', 'ner')
    processing = 'local'
    include = @('mapping')
} | ConvertTo-Json -Depth 100

$request = @{
    Method = 'Post'
    Uri = 'https://api.komplai.dk/v1/redact/file'
    Headers = $headers
    ContentType = 'application/json; charset=utf-8'
    Body = $body
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100
Python
import os

import requests

response = requests.post(
    "https://api.komplai.dk/v1/redact/file",
    headers={
        "Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
    },
    json={
        "file": {
            "filename": "afgoerelse.pdf",
            "contentType": "application/pdf",
            "data": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo=",
        },
        "detectors": ["regex", "ner"],
        "processing": "local",
        "include": ["mapping"],
    },
    timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())
JavaScript
const response = await fetch("https://api.komplai.dk/v1/redact/file", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    file: {
      filename: "afgoerelse.pdf",
      contentType: "application/pdf",
      data: "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo=",
    },
    detectors: ["regex", "ner"],
    processing: "local",
    include: ["mapping"],
  }),
});

console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.komplai.dk/v1/redact/file");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));
request.Content = new StringContent(@"{
  ""file"": {
    ""filename"": ""afgoerelse.pdf"",
    ""contentType"": ""application/pdf"",
    ""data"": ""JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo=""
  },
  ""detectors"": [""regex"", ""ner""],
  ""processing"": ""local"",
  ""include"": [""mapping""]
}", Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
    Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());

Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.

Svar
200 OK
{
  "redacted": "Afgørelse til [PERSON-1]\ncpr-nr. [CPR-1], [ADRESSE-1]\n\nTelefon [TLF-1]\n[EMAIL-1]",
  "engine": "pipeline",
  "mode": "ner",
  "processing": "local",
  "policy": "all-detected",
  "policyVersion": "redact-text-v1",
  "offsetEncoding": "utf-16",
  "charsIn": 131,
  "charsOut": 80,
  "truncated": false,
  "degraded": false,
  "configuration": {
    "engine": "pipeline",
    "mode": "ner",
    "detectors": ["regex", "ner"],
    "sources": [],
    "processing": "local"
  },
  "execution": {
    "completed": true,
    "detectorsRun": ["regex", "ner"],
    "detectionPasses": 1,
    "nerCalls": 1,
    "llmCalls": 0
  },
  "mapping": {
    "[PERSON-1]": "Mette Kjærgaard Holm",
    "[CPR-1]": "120385-1234",
    "[ADRESSE-1]": "Fiktivvej 12, 8000 Aarhus C",
    "[TLF-1]": "21 34 56 78",
    "[EMAIL-1]": "mette.holm@example.invalid"
  },
  "entries": [
    {
      "placeholder": "[PERSON-1]",
      "type": "person",
      "value": "Mette Kjærgaard Holm",
      "confidence": "medium",
      "source": "ner"
    },
    {
      "placeholder": "[CPR-1]",
      "type": "cpr",
      "value": "120385-1234",
      "confidence": "high",
      "source": "regex"
    },
    {
      "placeholder": "[ADRESSE-1]",
      "type": "address",
      "value": "Fiktivvej 12, 8000 Aarhus C",
      "confidence": "high",
      "source": "ner"
    },
    {
      "placeholder": "[TLF-1]",
      "type": "phone",
      "value": "21 34 56 78",
      "confidence": "medium",
      "source": "regex"
    },
    {
      "placeholder": "[EMAIL-1]",
      "type": "email",
      "value": "mette.holm@example.invalid",
      "confidence": "high",
      "source": "regex"
    }
  ],
  "file": {
    "type": "pdf",
    "bytes": 1025,
    "pageCount": 2
  },
  "pages": [
    {
      "number": 1,
      "start": 0,
      "end": 83,
      "hasText": true,
      "redactedStart": 0,
      "redactedEnd": 53
    },
    {
      "number": 2,
      "start": 85,
      "end": 131,
      "hasText": true,
      "redactedStart": 55,
      "redactedEnd": 80
    }
  ]
}
202 Accepted
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "queued",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 0
  },
  "reused": false,
  "file": {
    "type": "pdf",
    "bytes": 1025,
    "pageCount": 2
  },
  "pages": [
    {
      "number": 1,
      "start": 0,
      "end": 83,
      "hasText": true
    },
    {
      "number": 2,
      "start": 85,
      "end": 131,
      "hasText": true
    }
  ]
}
400 Bad Request
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "insufficient_scope",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/insufficient_scope"
}
409 Conflict
{
  "error": "processing_policy_changed",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/processing_policy_changed"
}
413 Content Too Large
{
  "error": "file_too_large",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/file_too_large"
}
415 Unsupported Media Type
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
422 Unprocessable Content
{
  "error": "invalid_file",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_file"
}
429 Too Many Requests
{
  "error": "processing_capacity_busy",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/processing_capacity_busy"
}
502 Bad Gateway
{
  "error": "incomplete_detection",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/incomplete_detection"
}
503 Service Unavailable
{
  "error": "redact_file_not_enabled",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/redact_file_not_enabled"
}
504 Gateway Timeout
{
  "error": "processing_timeout",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/processing_timeout"
}

Submit a PDF or Word file as a text job (beta) Beta

POST /v1/redact/file/jobs

Beta. Send a PDF with a text layer or a Word .docx as base64 in JSON; komplai extracts its text and runs the same Redact processing as for text, with the same options. The response is pseudonymised text, not a redacted file. No OCR runs: a scanned page is refused (422 scanned_pages_not_supported, with the page numbers) unless allowPagesWithoutText is true. The text is extracted on komplai's API servers (EU · Germany) in memory; the file is not stored. File problems: 400 unsupported_file_type, file_type_mismatch, invalid_file_encoding, empty_file; 413 file_too_large, too_many_pages, text_too_large, file_too_complex; 422 invalid_file, encrypted_file, no_text_found, scanned_pages_not_supported; 429 processing_capacity_busy while other files are being read. No method guarantees anonymity; check the result. The text is extracted while you wait and submitted as a text job, exactly as POST /v1/redact/jobs, up to 2,000,000 UTF-16 code units. The 202 response adds the file's page offsets in the extracted text; poll and read the result, restore and delete with the /v1/redact/jobs/{id} operations.

Organisation integration keys cannot use engine agentic: 403 integration_not_permitted.

Scopes
redact:process
Prøv kaldet

Kaldene er rigtige: komplai behandler det, du sender, hvert kald tæller med i nøglens grænser, og behandling i EU-cloud tæller med i organisationens månedlige loft for AI-forbrug. Brug testdata.

En nøgle, der starter med kp_org_ eller kp_live_. Den bliver på denne side, til du forlader den, og sendes kun til api.komplai.dk.

Parametre

Headere

  • idempotency-key string

    Optional. A new UUID for each job, in upper or lower case. If the connection drops, send the same request again with the same key: within the job's lifetime the same key and body return the same job (reused true) instead of a second one, and the same key with another body answers 409 idempotency_conflict. Never reuse a key for another text. The key is bound to your organisation, the owner (person or integration) and the API key. The default {{$guid}} is Postman's variable for a new UUID on each request; in other tools, generate a UUID for each job or leave the header out.

    Standard
    {{$guid}}
    Format
    uuid

Body i kaldet

  • file object påkrævet
    Underfelter (3)
    • filename string påkrævet

      The file's name. Its extension (.pdf or .docx) must match the content. Used only to check the type; not stored, logged or returned.

      Længde
      1 til 255
    • contentType string

      Optional. Must agree with the content when it names PDF or Word.

      En af
      application/pdf application/vnd.openxmlformats-officedocument.wordprocessingml.document application/octet-stream
      Standard
      application/octet-stream
    • data string påkrævet

      The file's bytes, base64 encoded (standard or URL-safe; line breaks are ignored). At most 50 MiB decoded and 2,000 PDF pages. PDF needs a text layer; Word .docx only, not .doc.

      Format
      byte
  • detectors string[]

    The layers to run, in any non-empty combination. regex: rules for CPR numbers, phone numbers, e-mail addresses and more. ner: a model for names, organisations and addresses. llm: a language model for what rules and NER miss, such as health data in free text; it can take up to a minute. It reads the text in parts of at most 12,000 characters. When its answer for a part cannot be used, that answer is discarded and the part is asked again in two overlapping halves, down to halves of 1,500 characters: at most 14 extra calls for a part. If an answer still cannot be used, the call fails with 502 invalid_detection or incomplete_detection and returns no result. Default regex and ner. The older field mode is still accepted but is not listed here: leave it out, because if you send both, they must agree (400 unsupported_engine_mode). engine agentic needs regex and llm, with optional ner.

    Standard
    ["regex", "ner"]
    Elementer
    1 til 3
    Unikke elementer
    Hvert element er en af
    regex ner llm
  • processing string

    Where the language model (llm) runs. local (default): komplai's local infrastructure in Denmark, with no AI charge. eu-cloud: komplai's EU cloud, which answers faster. It needs llm in detectors and EU processing approved for your organisation, and its usage counts towards the organisation's monthly AI spending cap (429 ai_credit_exhausted when the cap is reached). Every call to the model, including a part asked again in halves, is checked against the cap and counted on its own. Name the model in model, or leave it out for the default model there. Rules always run on komplai's servers in Germany (EU), and NER at the place in nerDeployment or, without one, at the default place GET /v1/access marks. GET /v1/access names where each layer processes text for your organisation, including eu-cloud, in services[].hosting.processing.layers. The API never switches between local and eu-cloud by itself.

    En af
    local eu-cloud
    Standard
    local
  • nerDeployment string kan være null

    Where the ner layer runs: eu-de (komplai's servers in Germany, EU) or local (komplai's local infrastructure in Denmark). Leave it out, or send null, for the default place: the one GET /v1/access marks with default true in the ner layer's places (services[].hosting.processing.layers), eu-de unless komplai has changed it. Each place there has available and a reason for the operations with detectors, and detect with the same for POST /v1/redact/detect and the operations without detectors, so check that the place you name is available for the operation you call. A place that cannot be used now answers 503 ner_location_unavailable and names the place in nerDeployment; NER never moves to another place. Needs ner in detectors (400 ner_deployment_without_ner); any other value answers 400 invalid_ner_deployment. The response names the place in configuration.nerDeployment (nerDeployment on POST /v1/redact/detect).

    En af
    eu-de local
    Standard
    null
  • nerModel string kan være null

    The NER model, by id from the ner layer's models in GET /v1/access. Leave it out, or send null, for the default model. An unknown id answers 400 ner_model_unknown, and a retired one or one that does not run at the place you name 400 ner_model_unavailable; a preview model needs your organisation's Redact preview, which an organisation integration key does not have (403 ner_model_preview_required). POST /v1/redact/detect, and the text operations without detectors, run only the default model (400 ner_model_unavailable for another). A model that is not set up at the default place on this server answers 503 ner_model_unconfigured; NER never runs another model. Needs ner in detectors (400 ner_model_without_ner). The response names the model in configuration.nerModel (nerModel on POST /v1/redact/detect).

    Standard
    null
  • model string kan være null

    The language model for llm, by id from GET /v1/access: the models of the llm layer for the processing you choose. Leave it out, or send null, for the default model there. Only models validated for Redact at that processing are accepted (400 llm_model_not_validated): qwen3.8-27b-q8 for local and mistral-small-3.2-24b-instruct-2506 for eu-cloud. GET /v1/access also lists models with reason not_validated, which cannot be chosen. A local model that local infrastructure does not offer right now answers 503 local_model_unavailable, and an EU model your organisation's EU route does not have answers 409 model_not_enabled. Without model, the default must be validated too: on local the server's default model, on eu-cloud the EU model the person behind a personal key saved, else the model on your organisation's EU route (409 llm_model_not_validated). The API never picks another model. Needs llm in detectors and engine pipeline (400 llm_model_not_applicable). configuration.llmModel names the model that ran.

    Standard
    null
  • policy string

    Always all-detected: everything found is replaced, under your organisation's redaction and allow rules.

    En af
    all-detected
    Standard
    all-detected
  • engine string Forhåndsversion

    Preview. Leave out. pipeline (default) runs the chosen detectors. agentic is an experimental method for organisations whose administrator has turned on the Redact Agentic preview (403 agentic_preview_not_enabled otherwise); an organisation integration key gets 403 integration_not_permitted. It needs processing local and detectors regex and llm, with optional ner. It reads the text in windows, so it takes the operation's own text limit; a long document belongs in a text job.

    En af
    pipeline agentic
    Standard
    pipeline
  • sources string[] Forhåndsversion

    Preview. Leave out. Lookup sources for engine agentic, chosen for each call. Each needs the administrator's approval and configured access; an unapproved or unavailable source refuses the call (403 agentic_lookup_not_allowed or 503 agentic_lookup_unavailable) and is never silently dropped. Default none.

    Standard
    []
    Elementer
    højst 5
    Unikke elementer
    Hvert element er en af
    cvr-official bbr web dar wikidata-local
  • include string[]

    As POST /v1/redact, plus source: the extracted text the offsets refer to. Every report except the bare result contains originals; protect it as personal information.

    Standard
    []
    Elementer
    højst 5
    Unikke elementer
    Hvert element er en af
    mapping findings changes skipped source
  • allowPagesWithoutText boolean

    A PDF page without a text layer (a scan, an image or a blank page) refuses the file with scanned_pages_not_supported, because no OCR runs. true processes the other pages and reports those pages with hasText false.

    Standard
    false

Svar

202 Accepted

The file's text was extracted and submitted as a text job. Location points to its status.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Location string

    The job's status: /v1/redact/jobs/{id}.

Body

  • id string påkrævet
    Format
    uuid
  • state string påkrævet
    En af
    queued running succeeded failed cancelled invalidated
  • createdAt string påkrævet
    Format
    date-time
  • expiresAt string påkrævet

    Application retention deadline. A queued job expires this long after it was submitted; a running job is kept for as long as its worker is alive; when the job ends, the retention period counts from the end. Results remain encrypted until explicit deletion or expiry; reads do not consume them.

    Format
    date-time
  • progress object påkrævet
    Underfelter (2)
    • completed integer påkrævet
      Værdi
      mindst 0
    • total integer påkrævet
      Værdi
      mindst 0
  • error string
  • reused boolean
  • file object påkrævet
    Underfelter (3)
    • type string påkrævet
      En af
      pdf docx
    • bytes integer påkrævet
      Værdi
      mindst 1
    • pageCount integer påkrævet
      Værdi
      mindst 1
  • pages object[] påkrævet

    Offsets in the extracted text, which is the job's source. Read the result from GET /v1/redact/jobs/{id}/result; with include changes, its changes map these offsets into redacted.

    Underfelter (4)
    • number integer påkrævet

      PDF page number. For .docx: body parts split at the page breaks Word recorded, then headers, footers, footnotes and endnotes, one part each.

      Værdi
      mindst 1
    • start integer påkrævet

      Start of the page in the extracted text (the source the other offsets refer to).

      Værdi
      mindst 0
    • end integer påkrævet

      Exclusive end in the extracted text.

      Værdi
      mindst 0
    • hasText boolean påkrævet

      false for a page without a text layer, only with allowPagesWithoutText.

  • source string

    Only with include source: the extracted text, pages separated by a blank line. Contains personal information.

    Længde
    højst 2.000.000
400 Bad Request

The request was refused before processing.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
401 Unauthorized

The key is missing or not valid.

Fejlkoder

  • api_key_required No Authorization: Bearer header with a komplai key.
  • invalid_api_key The key is unknown, expired, revoked or retired, the person behind a personal key is no longer a member or no longer assigned any app the key covers, or your organisation's API access for it is not set up or no longer active.
  • invalid_token The key was revoked or expired, or its access ended, while the request was admitted or processed.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
403 Forbidden

The key may not do this, or the organisation's access does not cover it.

Fejlkoder

  • insufficient_scope The key lacks a scope the operation needs (x-komplai-scopes): it was not issued or created with it, its person is no longer assigned the app, or the organisation's processing approval no longer covers it.
  • identity_retired The person behind a personal key has been removed from komplai.
  • approved_redact_storage_policy_required Your organisation processes personal data but has no approved storage policy for text jobs.
  • processing_access_withdrawn Access to the job was withdrawn after it was created: the agreement, the processing setup, the organisation's redaction rules or the storage policy for text jobs changed. The job is invalidated and its text and result are deleted. This is final: stop reading the job and do not reuse its Idempotency-Key; submit the text again as a new job when access allows it.
  • processing_choice_not_allowed The organisation does not allow this processing (local infrastructure or EU cloud) through the API, or the connection is not made available through the API.
  • processing_not_enabled The processing is not enabled for the app in the organisation: EU processing is not approved and enabled, or the agreement keeps processing on local infrastructure.
  • processing_not_approved The organisation's processing approval for the app is missing or was withdrawn.
  • app_not_assigned The key's person lost the app or their membership while the request was admitted.
  • ner_model_preview_required The NER model in nerModel is a preview. It needs your organisation's Redact preview, which an organisation integration key does not have.
  • integration_not_permitted An organisation integration key cannot use this operation or this option.
  • agentic_preview_not_enabled The organisation's administrator has not turned on the Redact Agentic preview.
  • agentic_lookup_not_allowed A source in sources is not approved by the organisation's administrator.
  • processing_access_changed The organisation's processing setup changed while the request was handled. Send it again.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
409 Conflict

Conflict with the current state.

Fejlkoder

  • idempotency_conflict This Idempotency-Key was used with a different body. Use a new UUID for a new job.
  • processing_access_changed The organisation's processing setup changed while the request was handled. Send it again.
  • model_not_enabled The model is not one you may use at this processing, or it is not offered there right now.
  • llm_model_not_validated The language model in model is not validated for Redact at the processing you chose. GET /v1/access lists the models you may name.
  • reasoning_effort_not_supported The reasoning effort komplai set for this EU language model in Redact is not one the model accepts on your organisation's EU route. Nothing was sent to the model, and the API does not send another effort.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
413 Content Too Large

Too large.

Fejlkoder

  • file_too_large The file is over 50 MiB, or the body is over its byte limit.
  • too_many_pages The PDF has more than 2,000 pages.
  • file_too_complex Reading the file took more than 120 seconds or more resources than allowed (memory, ZIP entries, XML size or depth).
  • text_too_large text is over the operation's limit in UTF-16 code units, or the body is over its byte limit.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
415 Unsupported Media Type

The body has no Content-Type, or one the API does not read, such as XML or form data. Send application/json.

Fejlkoder

  • invalid_body The body is not a JSON object with the documented fields: invalid JSON, Content-Type text/plain, an unknown field, a field of the wrong type, or a required field that is missing or blank.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
422 Unprocessable Content

The file cannot be read.

Fejlkoder

  • invalid_file file is missing or malformed (filename missing, blank, longer than 255 characters or with control characters; data not a string; an unknown key), or the PDF or Word file itself is damaged or not a Word document.
  • encrypted_file The PDF is password protected.
  • scanned_pages_not_supported A page has no text layer, for example a scan. No OCR runs. pages lists the pages; allowPagesWithoutText true processes the rest.
  • no_text_found The file contains no text at all.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
429 Too Many Requests

Refused for now. Wait the seconds in Retry-After before you try again.

Fejlkoder

  • processing_capacity_busy All organisation-rule workers in this API process are busy. There is no queue: try again after Retry-After.
  • rate_limited Too many requests: the per-minute limit of the person behind a personal key (shared with that person's other keys and use of the hub) or of the integration behind an organisation integration key (shared by its keys), the organisation's (120), the API's (300) or the per-IP network limit. Wait Retry-After seconds.

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
  • Retry-After integer påkrævet

    Seconds to wait before trying again (at most 60).

    Værdi
    1 til 60
  • x-ratelimit-limit integer

    Requests per minute allowed from your IP address (the per-IP network limit).

  • x-ratelimit-remaining integer

    Requests left in the current minute from your IP address.

  • x-ratelimit-reset integer

    Seconds until the per-IP window resets.

503 Service Unavailable

Processing is not available right now.

Fejlkoder

Headere

  • Request-Id string påkrævet

    This request's id: your X-Request-Id when you sent one valid UUID, otherwise a new UUID. An error body repeats it as request_id.

    Format
    uuid
KaldPOST /v1/redact/file/jobs
curl
curl https://api.komplai.dk/v1/redact/file/jobs \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "file": {
      "filename": "afgoerelse.pdf",
      "contentType": "application/pdf",
      "data": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo="
    },
    "detectors": ["regex", "ner"],
    "processing": "local",
    "include": ["mapping"]
  }'
PowerShell
$headers = @{
    Authorization = "Bearer $env:KOMPLAI_TOKEN"
}
$body = [ordered]@{
    file = [ordered]@{
        filename = 'afgoerelse.pdf'
        contentType = 'application/pdf'
        data = 'JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo='
    }
    detectors = @('regex', 'ner')
    processing = 'local'
    include = @('mapping')
} | ConvertTo-Json -Depth 100

$request = @{
    Method = 'Post'
    Uri = 'https://api.komplai.dk/v1/redact/file/jobs'
    Headers = $headers
    ContentType = 'application/json; charset=utf-8'
    Body = $body
}
$response = Invoke-RestMethod @request
$response | ConvertTo-Json -Depth 100
Python
import os

import requests

response = requests.post(
    "https://api.komplai.dk/v1/redact/file/jobs",
    headers={
        "Authorization": f"Bearer {os.environ['KOMPLAI_TOKEN']}",
    },
    json={
        "file": {
            "filename": "afgoerelse.pdf",
            "contentType": "application/pdf",
            "data": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo=",
        },
        "detectors": ["regex", "ner"],
        "processing": "local",
        "include": ["mapping"],
    },
    timeout=330,
)
print(response.status_code, response.headers.get("Request-Id"))
print(response.json())
JavaScript
const response = await fetch("https://api.komplai.dk/v1/redact/file/jobs", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KOMPLAI_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    file: {
      filename: "afgoerelse.pdf",
      contentType: "application/pdf",
      data: "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo=",
    },
    detectors: ["regex", "ner"],
    processing: "local",
    include: ["mapping"],
  }),
});

console.log(response.status, response.headers.get("Request-Id"));
console.log(await response.json());
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(330) };
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.komplai.dk/v1/redact/file/jobs");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("KOMPLAI_TOKEN"));
request.Content = new StringContent(@"{
  ""file"": {
    ""filename"": ""afgoerelse.pdf"",
    ""contentType"": ""application/pdf"",
    ""data"": ""JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMyAwIFIgPj4gPj4gL0NvbnRlbnRzIDUgMCBSID4+CmVuZG9iago1IDAgb2JqCjw8IC9MZW5ndGggMTMxID4+CnN0cmVhbQpCVCAvRjEgMTIgVGYgNzIgNzIwIFRkIDE2IFRMIChBZmf4cmVsc2UgdGlsIE1ldHRlIEtq5nJnYWFyZCBIb2xtKSBUaiBUKiAoY3ByLW5yLiAxMjAzODUtMTIzNCwgRmlrdGl2dmVqIDEyLCA4MDAwIEFhcmh1cyBDKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAzIDAgUiA+PiA+PiAvQ29udGVudHMgNyAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0xlbmd0aCA5NCA+PgpzdHJlYW0KQlQgL0YxIDEyIFRmIDcyIDcyMCBUZCAxNiBUTCAoVGVsZWZvbiAyMSAzNCA1NiA3OCkgVGogVCogKG1ldHRlLmhvbG1AZXhhbXBsZS5pbnZhbGlkKSBUaiBUKiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDIyNCAwMDAwMCBuIAowMDAwMDAwMzUwIDAwMDAwIG4gCjAwMDAwMDA1MzIgMDAwMDAgbiAKMDAwMDAwMDY1OCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjgwMgolJUVPRgo=""
  },
  ""detectors"": [""regex"", ""ner""],
  ""processing"": ""local"",
  ""include"": [""mapping""]
}", Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
if (response.Headers.TryGetValues("Request-Id", out var requestId))
{
    Console.WriteLine(string.Join(", ", requestId));
}
Console.WriteLine(await response.Content.ReadAsStringAsync());

Sæt først miljøvariablen KOMPLAI_TOKEN til din nøgle.

Svar
202 Accepted
{
  "id": "3f2b8c1e-7d4a-4e9b-a6c5-2d1e0f9a8b7c",
  "state": "queued",
  "createdAt": "2026-10-20T08:00:00.000Z",
  "expiresAt": "2026-10-20T09:00:00.000Z",
  "progress": {
    "completed": 0,
    "total": 0
  },
  "reused": false,
  "file": {
    "type": "pdf",
    "bytes": 1025,
    "pageCount": 2
  },
  "pages": [
    {
      "number": 1,
      "start": 0,
      "end": 83,
      "hasText": true
    },
    {
      "number": 2,
      "start": 85,
      "end": 131,
      "hasText": true
    }
  ]
}
400 Bad Request
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
401 Unauthorized
{
  "error": "api_key_required",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/api_key_required"
}
403 Forbidden
{
  "error": "insufficient_scope",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/insufficient_scope"
}
409 Conflict
{
  "error": "idempotency_conflict",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/idempotency_conflict"
}
413 Content Too Large
{
  "error": "file_too_large",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/file_too_large"
}
415 Unsupported Media Type
{
  "error": "invalid_body",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_body"
}
422 Unprocessable Content
{
  "error": "invalid_file",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/invalid_file"
}
429 Too Many Requests
{
  "error": "processing_capacity_busy",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/processing_capacity_busy"
}
503 Service Unavailable
{
  "error": "redact_file_not_enabled",
  "request_id": "0f8e2c4a-6b1d-4e3f-9a7c-5d2b8e1f4a60",
  "doc_url": "https://developers.komplai.dk/errors/redact_file_not_enabled"
}
komplaidevelopers
Kontakt os

Søg i dokumentationen

Vælg med piletasterne, og åbn med Enter.