ApplyToVolunteer Auth API

The Auth API from ApplyToVolunteer — 2 operation(s) for auth.

Operations 4

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/applytovolunteer-com:applytovolunteer-com-auth-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

applytovolunteer-com-auth-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Apply2Volunteer Auth API
  version: 1.0.0
  description: '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:
    name: Proprietary
    url: https://applytovolunteer.com/terms
servers:
- url: https://applytovolunteer.com
security:
- orgApiKey: []
tags:
- name: Auth
paths:
  /api/v1/auth/magic-link:
    post:
      operationId: sendMagicLink
      summary: Send a magic-link sign-in email
      description: Send a magic link. No API key.
      security: []
      requestBody:
        required: true
        description: JSON object with an email address.
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  description: Required. Trimmed and lowercased. Any non-empty string is accepted.
                next:
                  type: string
                  description: Post-login path. Kept only for /app, /app/..., or /tools/p/{token}. Any other value, including a non-string, is ignored.
                ref:
                  type: string
                  description: Campaign slug of letters, numbers, hyphens, and underscores, up to 32 characters. Email-shaped values are dropped. Non-strings are ignored.
                template:
                  type: string
                  description: Built-in template slug. Kept only for volunteer-application-form or volunteer-interest-form. Any other value is ignored.
              required:
              - email
              description: JSON object. email is required.
      responses:
        '200':
          description: Send a magic link
        '400':
          description: The body, query, or input failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '429':
          description: Too many requests from this network or organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
      tags:
      - Auth
  /api/v1/auth/verify:
    get:
      operationId: verifyMagicLink
      summary: Show the Continue page for a magic link
      description: 'A usable token returns 200 text/html and does not consume the token. That includes Sec-Fetch-Site cross-site, Purpose or Sec-Purpose prefetch, and a scanner user agent. The page title is Continue sign-in. The form POSTs to this URL with the same token. A known template slug says a form is not created until you continue. A plain link says the link is not used until you continue. HEAD does not consume a token and does not set a session cookie. A usable link returns 200 text/html with an empty body and Cache-Control no-store. A missing token stays 400 { error: "token required" } for every Accept. prefersHtml GET and HEAD of an unknown, expired, wrong-purpose, or non-replay used token return 410 text/html, Cache-Control no-store, X-Robots-Tag noindex, nofollow, noarchive. The page says the link expired or was already used and links to /login or /login?template={slug}. HEAD body is empty. JSON Accept, a missing Accept, and a tie with explicit JSON stay 400 { error: "invalid or expired" }. Signed-in prefersHtml GET of a used token is still 302 to /login?template={slug} for a known template slug, or to /app for a plain link, and does not set a session cookie. Signed-in prefersHtml HEAD of a used token is the 410 page, not 302 and not 400. Every verify response sends X-Robots-Tag noindex at minimum. The continue page keeps noindex, nofollow, noarchive. No API key.'
      security: []
      parameters:
      - schema:
          type: string
          description: Magic-link token from the email.
        required: true
        description: Magic-link token from the email.
        name: token
        in: query
      responses:
        '200':
          description: Usable magic link, template or plain. text/html page titled Continue sign-in. The token is not consumed. The form POSTs to this URL with the same token.
          content:
            text/html:
              schema:
                type: string
        '302':
          description: Used token on GET when prefersHtml is true and a valid session is present. Redirects to /login?template={slug} for a known template slug, or to /app for a plain link. Does not set a session cookie. The token stays used. HEAD does not use this redirect.
        '400':
          description: '{ error: "token required" } when the token query is missing. { error: "invalid or expired" } when the token is unknown, used, expired, or the wrong purpose.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '410':
          description: prefersHtml GET and HEAD of an unknown, expired, wrong-purpose, or non-replay used token. text/html. Cache-Control no-store. X-Robots-Tag noindex, nofollow, noarchive. The page says the link expired or was already used and links to /login or /login?template={slug}. HEAD body is empty.
          content:
            text/html:
              schema:
                type: string
      tags:
      - Auth
    head:
      operationId: probeMagicLink
      summary: Probe a magic link without consuming it
      description: 'HEAD does not consume a token and does not set a session cookie. A usable link, template or plain, returns 200 text/html with an empty body and Cache-Control no-store. prefersHtml GET and HEAD of an unknown, expired, wrong-purpose, or non-replay used token return 410 text/html, Cache-Control no-store, X-Robots-Tag noindex, nofollow, noarchive. The page says the link expired or was already used and links to /login or /login?template={slug}. HEAD body is empty. A missing token stays 400 { error: "token required" } for every Accept. JSON Accept, a missing Accept, and a tie with explicit JSON stay 400 { error: "invalid or expired" }. An unknown, used, expired, or wrong-purpose token returns that JSON body when the Accept does not prefer HTML. Signed-in prefersHtml HEAD of a used token is the 410 page, not 302 and not 400. Every verify response sends X-Robots-Tag noindex at minimum. The continue page keeps noindex, nofollow, noarchive. No API key.'
      security: []
      parameters:
      - schema:
          type: string
          description: Magic-link token from the email.
        required: true
        description: Magic-link token from the email.
        name: token
        in: query
      responses:
        '200':
          description: Usable token. Empty body. text/html. Cache-Control is no-store. The token is not consumed and no session cookie is set.
        '400':
          description: '{ error: "token required" } when the token query is missing. { error: "invalid or expired" } when the token is unknown, used, expired, or the wrong purpose.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '410':
          description: prefersHtml GET and HEAD of an unknown, expired, wrong-purpose, or non-replay used token. text/html. Cache-Control no-store. X-Robots-Tag noindex, nofollow, noarchive. The page says the link expired or was already used and links to /login or /login?template={slug}. HEAD body is empty.
          content:
            text/html:
              schema:
                type: string
      tags:
      - Auth
    post:
      operationId: confirmMagicLink
      summary: Consume a magic link and start a session
      description: 'A same-origin POST with a usable token consumes it and returns 302 when the client IP is present. The client IP is checked before the token is consumed. A ready template draft redirects to /app/forms/{id}. No owner org redirects to /app. A draft still being created returns 200. If creating that draft throws, the response is 200 HTML that says the form could not be created yet and offers Try again. The session cookie is still set. The template cap returns 429. A plain link redirects to /app, a safe next path, /app/forms/{id} after a preview claim, /app?preview=expired, or /tools/p/{token}. When the token is already used, prefersHtml is true, and the request has a valid session, the response is 302 to /login?template={slug} for a known template slug, or to /app for a plain link. Any other Accept, or HTML without a valid session, returns 400 { error: "invalid or expired" }. A POST that fails sameOriginWrite returns 403 and does not consume the token. That includes a cross-site Sec-Fetch-Site. A present session cookie does not change that 403. When the cookie-mutation origin check refuses the POST, prefersHtml still selects the HTML page and any other Accept still selects the JSON error. When prefersHtml is true for Accept, the body is text/html titled Open this link in a current browser, with that sentence and a link to /login?template={slug} when the token meta has a known template slug. Otherwise that link is /login. Any other Accept, including a missing header, returns application/json { error: "forbidden" }. PUT, PATCH, and DELETE that fail the cookie-mutation origin check return that JSON error even when Accept prefers HTML. A missing token returns 400 { error: "token required" }. An unknown, used, expired, or wrong-purpose token returns 400 { error: "invalid or expired" } unless the used-token HTML session redirect above applies. A missing client IP returns 400 { error: "missing_client_ip" } and does not consume the token. When storing the session fails, the token stays unused, no session cookie is set, and the response is 503. prefersHtml receives text/html titled Sign-in could not be finished. The page says this link is still good and posts Try again to this URL. Any other Accept receives { error: "unavailable" }. Cache-Control is no-store and X-Robots-Tag is noindex, nofollow, noarchive. Every verify response sends X-Robots-Tag noindex at minimum. No API key. The handler does not read a request body.'
      security: []
      parameters:
      - schema:
          type: string
          description: Magic-link token from the email.
        required: true
        description: Magic-link token from the email.
        name: token
        in: query
      responses:
        '200':
          description: HTML while a draft is still being created, or after creating that draft throws. The failure page says the form could not be created yet and offers Try again. A session cookie is set. Retry-After is sent only while automatic retries remain. The form posts to /login?template={slug}. The token is already consumed.
          content:
            text/html:
              schema:
                type: string
        '302':
          description: Token consumed and a session cookie is set. A ready template draft redirects to /app/forms/{id}. No owner org redirects to /app. A plain link redirects to /app, a safe next path, /app/forms/{id} after a preview claim, /app?preview=expired, or /tools/p/{token}. A later POST of a used token with prefersHtml and a valid session redirects to /login?template={slug} or /app.
        '400':
          description: '{ error: "token required" } when the token query is missing. { error: "invalid or expired" } when the token is unknown, used, expired, or the wrong purpose. { error: "missing_client_ip" } when the client IP cannot be resolved. The token is not consumed.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '403':
          description: 'sameOriginWrite refused the POST, including a cross-site Sec-Fetch-Site. A present session cookie does not change the body. The token is not consumed. text/html when prefersHtml is true for Accept. The page says Open this link in a current browser and links to /login?template={slug} when the token meta has a known template slug, or to /login when it does not. application/json { error: "forbidden" } for every other Accept.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
        '429':
          description: Template rate-limit HTML. A session cookie is set. No draft is created. The token is already consumed.
          content:
            text/html:
              schema:
                type: string
        '503':
          description: 'The session row could not be stored. The token stays unused and no session cookie is set. text/html titled Sign-in could not be finished when prefersHtml is true. The page says this link is still good and posts Try again to this URL. application/json { error: "unavailable" } for every other Accept. Cache-Control is no-store. X-Robots-Tag is noindex, nofollow, noarchive.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
      tags:
      - Auth
components:
  schemas:
    ApiError:
      type: object
      properties:
        error:
          type: string
          description: Short error code or message.
        message:
          type: string
          description: Human-readable detail when the handler sends one.
        fields:
          type: object
          additionalProperties:
            type: string
          description: Field-level validation messages.
        retryable:
          type: boolean
          description: Set on some public submit conflicts.
      required:
      - error
  securitySchemes:
    orgApiKey:
      type: http
      scheme: bearer
      bearerFormat: a2v API key
      description: 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.