ScholAccess DocAble › Developer API

Developer API Reference

Swagger UI  ·  OpenAPI JSON

Contents

  1. Authentication
  2. Core developer workflow
  3. Endpoint reference
    1. POST /api/upload
    2. POST /api/upload/init
    3. POST /api/upload/{upload_id}/chunk
    4. POST /api/upload/{upload_id}/complete
    5. GET /api/jobs/{job_id}
    6. GET /api/jobs/{job_id}/download
    7. GET /api/account
    8. OpenAPI spec & Swagger UI
  4. Job status values

1. Authentication

All endpoints require a Supabase JWT passed as a Bearer token. You must have an account — sign up or sign in.

Authorization header
Authorization: Bearer <your-supabase-access-token>
How to get a token
  1. Sign in at scholaccess.com/login.
  2. Open browser DevTools → Application tab → Local Storagehttps://scholaccess.com.
  3. Find the key whose value is a JSON object containing access_token. That JWT is your Bearer token.
  4. Send it as Authorization: Bearer <token> on every request.

Tokens expire (typically 1 hour). Refresh by re-visiting the site or using the Supabase SDK to call refreshSession(). Requests without a valid token return HTTP 401.

Plan limits. Free accounts have a monthly file quota. Paid accounts have higher quotas. Exceeding the quota returns HTTP 402 with a human-readable message. Check your current tier and remaining quota with GET /api/account.

2. Core developer workflow

Remediation is asynchronous. The typical integration is:

1
Upload — POST /api/upload

Send your file(s) as multipart/form-data. The response returns one job_id per accepted file. For files larger than 25 MB, use the chunked upload flow (/api/upload/init/chunk/complete) instead.

2
Poll status — GET /api/jobs/{job_id}

Poll every 3–10 seconds. Watch status and percent_done. Stop when status is COMPLETED, FAILED, or CANCELLED.

3
Download — GET /api/jobs/{job_id}/download

Follow the 302 redirect to a signed download URL. The remediated file has the same format and name as the original. Download links are valid for 7 days.

# Minimal shell example
TOKEN="eyJ..."   # your Supabase JWT (see "How to get a token" above)

# 1. Upload
JOB_ID=$(curl -s -X POST https://scholaccess.com/api/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F "files=@lecture.pptx" \
  | jq -r '.job_ids[0]')

# 2. Poll until done
while true; do
  STATUS=$(curl -s https://scholaccess.com/api/jobs/$JOB_ID \
    -H "Authorization: Bearer $TOKEN" | jq -r '.status')
  echo "Status: $STATUS"
  [ "$STATUS" = "COMPLETED" ] && break
  [ "$STATUS" = "FAILED" ]    && { echo "Job failed"; exit 1; }
  sleep 5
done

# 3. Download
curl -L -O -J https://scholaccess.com/api/jobs/$JOB_ID/download \
  -H "Authorization: Bearer $TOKEN"

3. Endpoint reference

POST /api/upload Auth required

Upload one or more files for accessibility remediation. Accepts PPTX, DOCX, PDF, XLSX, and common image formats (JPG, PNG, GIF, WebP, BMP, TIFF, HEIC). Each accepted file is queued and assigned a job ID. Files that are unsupported, too large (>25 MB), or exceed page/slide limits for your plan are reported in skipped but do not fail the request.

For files larger than 25 MB, use the chunked upload flow (/api/upload/init/chunk/complete) instead.
Request

Content-Type: multipart/form-data

FieldTypeRequiredDescription
filesfile (repeatable)Yes One or more files to remediate. Send each as a separate files part.
replace_suboptimal_altstringNo "true" or "1" — evaluate existing alt text and replace it when AI generates a better description.
Response 200 OK
FieldTypeDescription
job_idsstring[]UUID for each accepted file, in order.
skippedstring[]Human-readable reasons for rejected files (empty on full success).
Example
curl -X POST https://scholaccess.com/api/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F "files=@slides.pptx" \
  -F "files=@handout.pdf"
# Response
{
  "job_ids": ["a1b2c3d4-...", "e5f6a7b8-..."],
  "skipped": []
}

POST /api/upload/init Auth required

Begin a chunked upload for a single large file (typically >25 MB). Returns an upload_id and the server's preferred chunk size. Follow this with repeated POST /api/upload/{upload_id}/chunk calls, then finalize with POST /api/upload/{upload_id}/complete.

Request

Content-Type: application/json

FieldTypeRequiredDescription
filenamestringYes Original filename (with extension).
total_sizenumberYes Total file size in bytes.
content_typestringNo MIME type (inferred from filename if omitted).
replace_suboptimal_altbooleanNo See POST /api/upload.
Response 200 OK
FieldTypeDescription
upload_idstringIdentifier used in subsequent chunk / complete calls.
chunk_sizenumberRecommended chunk size in bytes.
Example
curl -X POST https://scholaccess.com/api/upload/init \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filename": "book.pdf", "total_size": 104857600}'

POST /api/upload/{upload_id}/chunk Auth required

Upload a single chunk of a chunked upload. Chunks must be sent sequentially starting at index 0. Returns the index of the next expected chunk.

Path parameters
ParameterDescription
upload_idFrom POST /api/upload/init.
Request

Content-Type: multipart/form-data

FieldTypeRequiredDescription
chunk_indexnumberYes Zero-based index of this chunk.
chunkfileYes Chunk bytes.
Response 200 OK
FieldTypeDescription
receivednumberTotal bytes received so far.
next_chunk_indexnumberIndex to send next.

POST /api/upload/{upload_id}/complete Auth required

Finalize a chunked upload. The server reassembles the chunks, validates the file, and enqueues the remediation job. Returns a job_id that you can poll with GET /api/jobs/{job_id}.

Path parameters
ParameterDescription
upload_idFrom POST /api/upload/init.
Response 200 OK
FieldTypeDescription
job_idstringUUID of the enqueued remediation job.
skippedstring[]Populated if the reassembled file was rejected (e.g., unsupported type).
Example
curl -X POST https://scholaccess.com/api/upload/abc123/complete \
  -H "Authorization: Bearer $TOKEN"

GET /api/jobs/{job_id} Auth required

Poll the status and metadata for a single remediation job. Returns 404 if the job does not exist or belongs to a different account.

Path parameters
ParameterDescription
job_idUUID returned by POST /api/upload.
Response fields (selected)
FieldTypeDescription
idstringJob UUID.
statusstringCurrent status — see Status values.
filenamestringOriginal uploaded filename.
percent_donenumberProgress 0–100. Live during processing; 100 on completion.
stage_detailstringHuman-readable phase label (e.g. "Remediating").
queue_positionnumber | nullPosition in queue; null once processing starts.
has_outputbooleantrue when the remediated file is ready for download.
errorstring | nullHuman-readable error message when status is FAILED.
error_typestring | nullMachine-readable error class for FAILED jobs.
post_checkobject | nullAccessibility check summary produced after remediation (when enabled).
chunk_progressobject | null{"completed": N, "total": N} for large PDFs split into chunks.
created_atstringISO 8601 timestamp.
Example
curl https://scholaccess.com/api/jobs/a1b2c3d4-... \
  -H "Authorization: Bearer $TOKEN"
# Response (completed)
{
  "id": "a1b2c3d4-...",
  "status": "COMPLETED",
  "filename": "slides.pptx",
  "percent_done": 100,
  "has_output": true,
  "post_check": { ... },
  "created_at": "2026-04-23T14:00:00Z"
}

GET /api/jobs/{job_id}/download Auth required

Download the remediated output file for a completed job. In production this returns a 302 redirect to a signed GCS download URL — use curl -L or follow redirects in your HTTP client. Returns 400 if the job is not yet completed.

The downloaded file has the same format (.pptx, .pdf, etc.) and the original filename. Signed URLs expire after a short window — download promptly after requesting this endpoint.
Example
# Download and save with the server-provided filename
curl -L -O -J https://scholaccess.com/api/jobs/a1b2c3d4-.../download \
  -H "Authorization: Bearer $TOKEN"

GET /api/account Auth required

Return the authenticated user's account information, including current plan tier and monthly usage / quota counts. Useful for client-side quota displays and for checking remaining capacity before a large upload.

Response fields (selected)
FieldTypeDescription
userobjectProfile info (id, email, name).
tierstringPlan name (e.g. free, starter, pro, power, unlimited).
quotaobjectMonthly quota: {"used": N, "limit": N}. limit may be null for unlimited plans.
institutionobject | nullLinked institution, if any.
subscriptionobject | nullActive subscription details (status, renewal date).
Example
curl https://scholaccess.com/api/account \
  -H "Authorization: Bearer $TOKEN"

OpenAPI spec & Swagger UI

The documented API endpoints are described by a machine-readable OpenAPI 3.x spec auto-generated by FastAPI. The spec contains only the endpoints documented on this page. All endpoints require the Authorization: Bearer header described in section 1.

URLDescription
/api/openapi.json OpenAPI JSON spec. Suitable for import into Postman, Insomnia, or code generators.
/api/docs Interactive Swagger UI — try endpoints directly in the browser.

4. Job status values

The status field in job responses takes one of these values:

PENDING PROCESSING COMPLETED FAILED CANCELLED
StatusMeaning
PENDINGJob is queued and waiting for a worker. Check queue_position.
PROCESSINGA worker is actively remediating the file. Check percent_done.
COMPLETEDRemediation finished. The output file is available at GET /api/jobs/{job_id}/download.
FAILEDRemediation failed. See error (human-readable) and error_type (machine-readable).
CANCELLEDCancelled by the user or the system. No output is available.
Terminal statesCOMPLETED, FAILED, and CANCELLED are terminal. Once a job reaches one of these states it will not change again. Stop polling when you see any of them.