Skip to content
Docs menu

Copy the text

Your browser did not allow copying. The text below is selected: press Ctrl+C, or ⌘C on a Mac.

Check a PDF for accessibility

Checks one PDF (up to 25 MB and 500 pages) against the machine-checkable criteria of PDF/UA. Send the file as multipart/form-data in the field file, or JSON with url or upload_id. Answers with 202 right away; ?wait=true (or a number of seconds, at most 30) waits for the result. The result counts the criteria met and lists the topics with problems, with steps to fix them. It is not a statement that the file meets legal requirements: a manual review is always needed. Costs at least 1 credit.

POSThttps://api.switchfile.io/v1/accessibility/checks

Needs an API key: Authorization: Bearer YOUR_API_KEY. See Authentication.

Example

curl "https://api.switchfile.io/v1/accessibility/checks?wait=true" \
  -H "Authorization: Bearer $SWITCHFILE_API_KEY" \
  -F file=@annual-report.pdf \
  -F report_pdf=en

Parameters

Query parameters

  • waitstring | number

    true or a number of seconds: wait until the check is done, at most 30 seconds

    one of "true" Ā· example: true

Headers

  • Idempotency-Keystring

    1 to 255 visible ASCII characters, for example a UUID. Send the request again with the same key after a timeout: nothing is created twice. Kept for 24 hours.

    example: 6f1c2b8e-1d8e-4c55-9f0e-3f3f0b0a8f21

  • X-End-Userstring

    Service keys only: an ID for the visitor you act for (1 to 128 characters: letters, digits and . _ : @ -). Quotas and rate limits then count per visitor.

  • X-End-User-Ipstring

    Required with X-End-User: the IP address of the visitor.

Request body

As application/json

  • filenamestring

    File name shown in the report

    1 to 255 characters

  • profilestring

    PDF/UA part to check against. auto (default) picks it from the file and falls back to PDF/UA-1

    one of "auto"

  • report_pdfstring

    Also create the report as an accessible PDF in this language

    one of "en"

  • upload_idstring (uuid)

    ID from POST /v1/uploads

  • urlstring

    Public URL of the PDF

    at most 4096 characters Ā· matches ^https?://

As multipart/form-data

  • filefilerequired

    The PDF, up to 25 MB and 500 pages

  • filenamestring

    File name shown in the report

  • profilestring

    PDF/UA part to check against

    one of "auto", "ua1", "ua2"

  • report_pdfstring

    Also create the report as a PDF in this language

    one of "en"

Responses

  • 200Done within wait
    • created_atstringrequired

      ISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00

    • creditsstring (integer) | integerrequired

      Credits used, set once the check is done

    • errorobject | nullrequired
    • error.codestringrequired
    • error.messagestringrequired
    • expires_atstring | nullrequired

      Input and report are deleted at this time

    • finished_atstring | nullrequired

      ISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00

    • idstring (uuid)required
    • inputobjectrequired
    • input.filenamestring | nullrequired
    • input.sizestring (integer) | integerrequired
    • linksobjectrequired
    • links.selfstringrequired
    • objectstringrequired

      one of "accessibility_check"

    • profilestringrequired

      one of "auto", "ua1", "ua2"

    • report_pdfstring | nullrequired

      Also create the report as an accessible PDF in this language

      one of "en"

    • resultobject | nullrequired
    • result.completebooleanrequired

      false if the time limit was reached; the counts cover only the checked part

    • result.criteriaobjectrequired
    • result.criteria.appliedstring (integer) | integerrequired

      Machine-checkable criteria that apply to this file

      at least 0

    • result.criteria.failedstring (integer) | integerrequired

      at least 0

    • result.criteria.metstring (integer) | integerrequired

      at least 0

    • result.manual_review_neededbooleanrequired

      Always true: software cannot check everything. A person who knows the content has to review it

      one of true

    • result.pagesstring (integer) | integerrequired

      at least 0

    • result.profilestringrequired

      one of "ua1", "ua2"

    • result.report_json_urlstringrequired

      Signed URL of the full report as JSON

    • result.report_pdf_urlstring | nullrequired

      Signed URL of the report as PDF (with report_pdf)

    • result.summarystringrequired

      X of Y machine-checkable criteria met; manual review needed

    • result.topicsAccessibilityTopic[]required

      Topics with failed criteria, most failed checks first

    • result.topics[].explanationstringrequired

      What the problem means for people who use assistive technology

    • result.topics[].failed_checksstring (integer) | integerrequired

      Number of failed checks in this topic

      at least 0

    • result.topics[].fixobjectrequired
    • result.topics[].fix.acrobatstring[]required

      Steps in Adobe Acrobat Pro

    • result.topics[].fix.indesignstring[]required

      Steps in Adobe InDesign

    • result.topics[].fix.wordstring[]required

      Steps in Microsoft Word

    • result.topics[].idstringrequired

      Stable topic ID, for example alt-text

    • result.topics[].pagesstring (integer) | integer[]required

      Affected pages, at most 100

    • result.topics[].titlestringrequired
    • statusstringrequired

      one of "queued", "processing", "finished", "failed"

    200 application/json
    {
      "id": "8c3e5a71-2f4b-4d6a-9e0c-7b1d3f5a2e48",
      "object": "accessibility_check",
      "status": "finished",
      "input": {
        "filename": "annual-report.pdf",
        "size": 482113
      },
      "profile": "auto",
      "report_pdf": "en",
      "result": {
        "summary": "38 of 41 machine-checkable criteria met; manual review needed",
        "profile": "ua1",
        "complete": true,
        "pages": 12,
        "criteria": {
          "applied": 41,
          "met": 38,
          "failed": 3
        },
        "manual_review_needed": true,
        "topics": [
          {
            "id": "alt-text",
            "title": "Figure or formula has no alternative text",
            "explanation": "A Figure or Formula tag has neither alternative text (/Alt) nor replacement text (/ActualText). Screen readers then announce only that there is a graphic, or skip it, so blind users miss information that exists only in the image, such as the message of a chart or the content of a formula.",
            "fix": {
              "word": [
                "Right-click the picture and choose View Alt Text (Office 2019 to 2024: Edit Alt Text)."
              ],
              "indesign": [
                "Select the image and choose Object > Object Export Options > Alt Text."
              ],
              "acrobat": [
                "Choose All tools > Prepare for accessibility > Add alternate text."
              ]
            },
            "failed_checks": 5,
            "pages": [
              1,
              2,
              7
            ]
          }
        ],
        "report_json_url": "https://api.switchfile.io/files/2a6f8e1c-4b3d-4e7a-9c5f-8d1b0e2a4c67/report.json?expires=1762538401&signature=3f9c2a7d41e8b6c05d1f9e2a7b4c8d3e6f0a1b2c3d4e5f60718293a4b5c6d7e8",
        "report_pdf_url": "https://api.switchfile.io/files/2a6f8e1c-4b3d-4e7a-9c5f-8d1b0e2a4c67/report.pdf?expires=1762538401&signature=3f9c2a7d41e8b6c05d1f9e2a7b4c8d3e6f0a1b2c3d4e5f60718293a4b5c6d7e8"
      },
      "error": null,
      "credits": 1,
      "created_at": "2026-11-06T18:00:00+00:00",
      "finished_at": "2026-11-06T18:00:02+00:00",
      "expires_at": "2026-11-07T18:00:02+00:00",
      "links": {
        "self": "https://api.switchfile.io/v1/accessibility/checks/8c3e5a71-2f4b-4d6a-9e0c-7b1d3f5a2e48"
      }
    }
  • 202Created, still running. Poll links.self with ?wait=true
    • created_atstringrequired

      ISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00

    • creditsstring (integer) | integerrequired

      Credits used, set once the check is done

    • errorobject | nullrequired
    • error.codestringrequired
    • error.messagestringrequired
    • expires_atstring | nullrequired

      Input and report are deleted at this time

    • finished_atstring | nullrequired

      ISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00

    • idstring (uuid)required
    • inputobjectrequired
    • input.filenamestring | nullrequired
    • input.sizestring (integer) | integerrequired
    • linksobjectrequired
    • links.selfstringrequired
    • objectstringrequired

      one of "accessibility_check"

    • profilestringrequired

      one of "auto", "ua1", "ua2"

    • report_pdfstring | nullrequired

      Also create the report as an accessible PDF in this language

      one of "en"

    • resultobject | nullrequired
    • result.completebooleanrequired

      false if the time limit was reached; the counts cover only the checked part

    • result.criteriaobjectrequired
    • result.criteria.appliedstring (integer) | integerrequired

      Machine-checkable criteria that apply to this file

      at least 0

    • result.criteria.failedstring (integer) | integerrequired

      at least 0

    • result.criteria.metstring (integer) | integerrequired

      at least 0

    • result.manual_review_neededbooleanrequired

      Always true: software cannot check everything. A person who knows the content has to review it

      one of true

    • result.pagesstring (integer) | integerrequired

      at least 0

    • result.profilestringrequired

      one of "ua1", "ua2"

    • result.report_json_urlstringrequired

      Signed URL of the full report as JSON

    • result.report_pdf_urlstring | nullrequired

      Signed URL of the report as PDF (with report_pdf)

    • result.summarystringrequired

      X of Y machine-checkable criteria met; manual review needed

    • result.topicsAccessibilityTopic[]required

      Topics with failed criteria, most failed checks first

    • result.topics[].explanationstringrequired

      What the problem means for people who use assistive technology

    • result.topics[].failed_checksstring (integer) | integerrequired

      Number of failed checks in this topic

      at least 0

    • result.topics[].fixobjectrequired
    • result.topics[].fix.acrobatstring[]required

      Steps in Adobe Acrobat Pro

    • result.topics[].fix.indesignstring[]required

      Steps in Adobe InDesign

    • result.topics[].fix.wordstring[]required

      Steps in Microsoft Word

    • result.topics[].idstringrequired

      Stable topic ID, for example alt-text

    • result.topics[].pagesstring (integer) | integer[]required

      Affected pages, at most 100

    • result.topics[].titlestringrequired
    • statusstringrequired

      one of "queued", "processing", "finished", "failed"

    202 application/json
    {
      "id": "8c3e5a71-2f4b-4d6a-9e0c-7b1d3f5a2e48",
      "object": "accessibility_check",
      "status": "queued",
      "input": {
        "filename": "annual-report.pdf",
        "size": 482113
      },
      "profile": "auto",
      "report_pdf": "en",
      "result": null,
      "error": null,
      "credits": null,
      "created_at": "2026-11-06T18:00:00+00:00",
      "finished_at": null,
      "expires_at": null,
      "links": {
        "self": "https://api.switchfile.io/v1/accessibility/checks/8c3e5a71-2f4b-4d6a-9e0c-7b1d3f5a2e48"
      }
    }
  • 401The API key is missing or not valid
    401 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-unauthenticated",
      "title": "Unauthenticated",
      "status": 401,
      "code": "UNAUTHENTICATED",
      "detail": "Missing or invalid API key."
    }
  • 402Today's free quota is used up and there are not enough credits
    402 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-credits-exceeded",
      "title": "Credits exceeded",
      "status": 402,
      "code": "CREDITS_EXCEEDED",
      "detail": "Today's free quota is used up and there are not enough credits left."
    }
  • 403X-End-User was sent with a key that is not a service key, or the account converts without storage (no_store, STORAGE_DISABLED)
    403 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-end-user-not-allowed",
      "title": "End user not allowed",
      "status": 403,
      "code": "END_USER_NOT_ALLOWED",
      "detail": "The X-End-User header is only allowed with a service key."
    }
  • 404upload_id was not found
    404 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-not-found",
      "title": "Not found",
      "status": 404,
      "code": "NOT_FOUND",
      "detail": "Upload not found."
    }
  • 409No file has been uploaded for this upload_id yet (UPLOAD_INCOMPLETE), or the request with this Idempotency-Key is still running
    409 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-upload-incomplete",
      "title": "Upload incomplete",
      "status": 409,
      "code": "UPLOAD_INCOMPLETE",
      "detail": "No file has been uploaded for this upload_id yet."
    }
  • 413The request or the file is too large
    413 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-file-too-large",
      "title": "File too large",
      "status": 413,
      "code": "FILE_TOO_LARGE",
      "detail": "The file is larger than 25 MB, the limit for accessibility checks."
    }
  • 415Send JSON or multipart/form-data
    415 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-unsupported-media-type",
      "title": "Unsupported media type",
      "status": 415,
      "code": "UNSUPPORTED_MEDIA_TYPE",
      "detail": "Send JSON or multipart/form-data."
    }
  • 422Invalid data or a bad URL
    422 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-invalid-data",
      "title": "Invalid data",
      "status": 422,
      "code": "INVALID_DATA",
      "detail": "The request contains invalid data.",
      "errors": {
        "source": [
          "Set exactly one of url and upload_id, or send the file as multipart/form-data."
        ]
      }
    }
  • 429Too many requests or a daily quota is used up. See Retry-After
    429 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-rate-limit-exceeded",
      "title": "Rate limit exceeded",
      "status": 429,
      "code": "RATE_LIMIT_EXCEEDED",
      "detail": "Too many requests. Try again in 12 seconds."
    }
  • 503Accessibility checks are switched off on this server
    503 application/problem+json
    {
      "type": "https://switchfile.io/docs/api/v1#errors-engine-unavailable",
      "title": "Engine unavailable",
      "status": 503,
      "code": "ENGINE_UNAVAILABLE",
      "detail": "PDF accessibility checks are not available right now. Try again later."
    }

Error bodies and codes are explained in Errors.