# Apply2Volunteer API

https://applytovolunteer.com/docs/api

Convert volunteer PDFs into progressive online forms. Organization owners and admins create API keys in the dashboard. Send a key as Authorization: Bearer a2v_... The token starts with a2v_. This API does not implement OAuth. Public submit and anonymous grade or convert do not accept the key in place of a Turnstile token. Keyless agents use /mcp and POST /a2a for anonymous grade and preview.

License: [Proprietary](https://applytovolunteer.com/terms)

Organization API key. REST reads Authorization and accepts only the exact prefix "Bearer " (capital B, one space) followed by a token that starts with a2v_. Put the a2v_ token in the bearer credential. Do not include the word Bearer in the token. Owners and admins create keys at /app/settings/api-keys. The secret is shown once. Revoked keys are rejected. This API does not implement OAuth. Scopes are forms:read, forms:write, applications:read, and applications:write. forms:write does not include forms:read. A new key defaults to forms:read and forms:write. applications:read and applications:write are opt-in. A browser session cookie is also accepted on organization routes. Agents send the bearer key.

## Operations

### GET /api/v1/me

operationId: getCurrentSession

Current session and organizations

Current session and orgs. An org API key is not read. Only a browser session cookie is. With no cookie the response is 200 and user is null.

### POST /api/v1/auth/magic-link

operationId: sendMagicLink

Send a magic-link sign-in email

Send a magic link. No API key.

### GET /api/v1/auth/verify

operationId: verifyMagicLink

Consume a magic link and start a session

Consume a magic link. No API key. Success redirects (302) to the next path or the dashboard.

### POST /api/v1/conversions

operationId: createConversion

Start a PDF or URL conversion

Ingest a PDF/URL (auth, rate-limited). Requires a browser session or an org API key with forms:write. The key's organization must match orgId when orgId is set.

### GET /api/v1/conversions/{id}

operationId: getConversion

Poll a conversion

Poll a conversion. Requires a browser session or an org API key with forms:read. A missing or wrong key is 404, not 401.

### GET /api/v1/forms

operationId: listForms

List forms in an organization

List org forms. Requires a browser session or an org API key with forms:read. A missing or wrong key is 404, not 401.

### POST /api/v1/forms

operationId: createForm

Create a form from a conversion or a blank form

Create a form from a conversion or blank. Requires forms:write on the orgId in the body. No session and no key is 401. A key for another organization is 404. A key missing forms:write is 403. A blank create from an org API key shares 60 per organization per hour with MCP. A website session is not counted.

### GET /api/v1/forms/{id}

operationId: getForm

Get a form and its current version

Get a form and its current version. Requires a browser session or an org API key with forms:read. A missing or wrong key is 404, not 401.

### PATCH /api/v1/forms/{id}

operationId: updateForm

Update a form title, settings, or fields

Update form title, settings, or fields. Add a field by omitting its id. op add also inserts a field and must not include an id. Remove a field with op remove or removeFieldIds. New field ids are returned on added. Requires a browser session or an org API key with forms:write. A missing or wrong key is 404, not 401. An org API key shares 60 updates per organization per hour with MCP, including adds and removes. A website session is not counted. A field id that is not on the current draft is 409. A field whose key has answers or consents on any version of the form cannot be removed. A field key that already has answers or consents cannot be changed. Help text is at most 2000 characters.

### POST /api/v1/forms/{id}/publish

operationId: publishForm

Publish a new locked form version

Publish a new locked version. A form with no fields is rejected. Publish is refused when it would remove a field that already has answers or consents. Requires a browser session or an org API key with forms:write. A missing or wrong key is 404, not 401. No request fields are read. A form with no fields is 400. Dropping a field key that already has answers or consents is 409.

### POST /api/v1/forms/{id}/repair-identities

operationId: repairFormFieldIdentities

Remint invalid draft field ids

Remint invalid draft field ids (owner). Requires a browser session or an org API key with forms:write. A missing or wrong key is 404, not 401. No request fields are read.

### POST /api/v1/forms/{id}/discard

operationId: discardFormDraft

Discard the open draft version

Discard the open draft version. Requires a browser session or an org API key with forms:write. A missing or wrong key is 404, not 401. No request fields are read.

### GET /api/v1/forms/{id}/grade

operationId: gradeSavedForm

Grade the current saved form version

Owner/org grade for the current form version (auth). Use this for org-internal grades; they have no public /tools/r/{id} share link. Requires a browser session or an org API key with forms:read. A missing or wrong key is 404, not 401.

### GET /api/v1/forms/{id}/applications

operationId: listFormApplications

List applications for a form

List applications for a form. Requires a browser session or an org API key with applications:read. A missing or wrong key is 404, not 401. forms:read does not include this scope.

### GET /api/v1/applications/{id}

operationId: getApplication

Get an application

Get an application. Requires a browser session or an org API key with applications:read. A missing or wrong key is 404, not 401.

### PATCH /api/v1/applications/{id}

operationId: updateApplicationStatus

Update an application status

Update application status (FCRA-gated decline). Requires a browser session or an org API key with applications:write. A missing or wrong key is 404, not 401. Declining requires declineReason background_check, not_a_fit, or incomplete.

### POST /public/forms/{org}/{form}/submit

operationId: submitPublicForm

Submit stage 1 of a public form

Public stage-1 submit. No org API key. Anonymous calls need a Turnstile token in production. A failed check is 400 with error turnstile. A missing Turnstile configuration is 503. Dev and test skip verification. Keyless agents should use /mcp or POST /a2a instead of calling this route without a token. This route does not submit through /mcp or /a2a.

### POST /public/continue/{token}/submit

operationId: submitContinueStage

Submit a continue-link stage

Continue-link stage submit. No org API key. Anonymous calls need a Turnstile token in production. A failed check is 400 with error turnstile. A missing Turnstile configuration is 503. Dev and test skip verification. Keyless agents should use /mcp or POST /a2a instead of calling this route without a token.

### POST /api/v1/tools/grade

operationId: gradePublicForm

Grade a volunteer form

Form Grader (upload, URL, pasted, or form id). id and reportUrl (/tools/r/{id}) are present only for public grades. Saved-form grades omit id and reportUrl; owners use GET /api/v1/forms/{id}/grade. Anonymous grades omit restricted field labels from parsed; the score still counts them. The API key is optional. Anonymous calls need a Turnstile token in production. A failed check is 400 with error turnstile. A missing Turnstile configuration is 503. Dev and test skip verification. Keyless agents should use /mcp or POST /a2a instead of calling this route without a token. formId or formVersionId requires forms:read and does not use Turnstile. A key without forms:read is treated as anonymous.

### GET /api/v1/tools/grade/{id}

operationId: getPublicGrade

Fetch a public Form Grader report

Fetch a public Form Grader report. Org-internal grades 404. Restricted field labels are omitted; the stored score is unchanged. No API key. Org-internal grades are 404.

### POST /api/v1/tools/convert

operationId: createFormPreview

Create a public converter preview

Public convert preview (size-capped). The API key is optional. Anonymous calls need a Turnstile token in production. A failed check is 400 with error turnstile. A missing Turnstile configuration is 503. Dev and test skip verification. Keyless agents should use /mcp or POST /a2a instead of calling this route without a token. formId and formVersionId are rejected. A key with forms:read stores the preview on that organization. A key without forms:read is treated as anonymous.

### GET /api/v1/tools/previews/{id}

operationId: getFormPreview

Fetch a converter preview

Fetch a converter preview. No API key.

### POST /api/v1/tools/previews/{id}/claim

operationId: claimFormPreview

Claim a preview as an organization draft

Claim a preview as an org draft form. 200 returns formId and versionId. 202 { pending: true } means the same organization already reserved this preview and the draft is still being saved; retry. 409 is a different organization. Requires an org API key with both forms:read and forms:write, or a browser session that is an owner or admin. forms:read resolves the organization. forms:write saves the draft. A key with only forms:write is 401. The organization comes from the key, not the body. No request fields are read.

Machine-readable API catalog (RFC 9727): https://applytovolunteer.com/.well-known/api-catalog
