Browse documentation
METAPHRASE / ENDPOINTSREST API v1
Open in AI
Open in ChatGPT Open in Claude
Markdown

cite

Generate a citation and BibTeX/RIS exports from source metadata, without an LLM.

Endpoint and method

POST https://metaphrase.msalman.com/api/v1/cite

Authentication

Send Authorization: Bearer <key> and Content-Type: application/json. Create a key at the dashboard. Store it in backend environment variable METAPHRASE_API_KEY; never expose it in a browser, mobile binary, public repository, or widget. See authentication and a working backend proxy.

Request parameters

JSON uses snake_case. Unknown fields are rejected. Omit optional values instead of sending null. Maximum text length: 20,000 Unicode code points.

NameTypeRequiredDefaultAllowed values / rangeMax length / items
source_typestringNo"auto"auto, url, doi, isbn, manual—
sourcestringUnless source_type=manual——2048
stylestringNo"apa"apa, mla, chicago, harvard, ieee—
fieldsobjectIf source_type=manual———
fields.typestringNo"webpage"webpage, book, article-journal—
fields.titlestringYes——500
fields.authorsarrayNo[]—50
fields.authors[].givenstringNo——120
fields.authors[].familystringNo——120
fields.authors[].literalstringNo——250
fields.yearintegerNo—1 to 9999—
fields.monthintegerNo—1 to 12—
fields.dayintegerNo—1 to 31—
fields.urlstringNo—uri2048
fields.publisherstringNo——250
fields.container_titlestringNo——300
fields.volumestringNo——40
fields.issuestringNo——40
fields.pagesstringNo——80
fields.doistringNo——255
fields.isbnstringNo——25
fields.accessed_datestringNo—date—
streambooleanNofalsefalse—
  • source_type: auto recognizes DOI, public HTTP(S) URL or ISBN; manual requires fields instead of source.
  • source: A DOI (plain or doi.org URL), a checksum-valid ISBN-10/13, or a public HTTP(S) page URL. Private networks, credentials and nonstandard ports are rejected.
  • style: apa=APA 7; mla=MLA 9; chicago=Chicago 18 author-date; harvard=Cite Them Right 12; ieee=IEEE.
  • fields: Manual source metadata. Required only for source_type=manual; title is required. Other missing metadata is reported in warnings.
  • stream: Use true for SSE on paraphrase/rewrite, translate or summarize. Other operations require false; alternatives always returns JSON.

Use fields only with source_type=manual; fields.title is required. Every author needs family or literal; month requires year, and day requires a valid month/year date. Omit unknown values instead of sending null. auto recognizes DOI URLs/plain DOI, HTTP(S) URL, or checksum-valid ISBN. URL metadata reads only public HTTP(S) pages on ports 80/443, checks every redirect and pins validated DNS. Use manual fields for blocked, scanned, missing or incomplete metadata. Styles: APA 7, MLA 9, Chicago 18 author-date, Harvard Cite Them Right 12 and IEEE. Copy bibtex into a .bib file or ris into a .ris file.

Full example request

{
  "source_type": "manual",
  "style": "apa",
  "fields": {
    "type": "book",
    "title": "A clear idea",
    "authors": [
      {
        "given": "Ada",
        "family": "Lovelace"
      }
    ],
    "year": 2024,
    "publisher": "Example Press"
  },
  "stream": false
}

Full example response

HTTP 200, application/json. This is an illustrative response; writing, source metadata, token counts and cost can vary. request_id is a server-generated UUID. Cache hits use usage.cached=true and report zero new tokens/cost. usage_estimated=true means the provider did not supply exact token counts.

{
  "request_id": "019b8df0-1234-4000-8000-000000000006",
  "tool": "cite",
  "result": {
    "text": "Lovelace, A. (2024). A clear idea. Example Press.",
    "style": "apa",
    "style_name": "APA 7",
    "source_type": "manual",
    "metadata": {
      "type": "book",
      "title": "A clear idea",
      "authors": [
        {
          "given": "Ada",
          "family": "Lovelace"
        }
      ],
      "year": 2024,
      "publisher": "Example Press"
    },
    "bibtex": "@book{mpfda3a81f9b10,\n  author = {Lovelace, Ada},\n  title = {A clear idea},\n  year = {2024},\n  publisher = {Example Press}\n}\n",
    "ris": "TY  - BOOK\nAU  - Lovelace, Ada\nTI  - A clear idea\nPY  - 2024\nPB  - Example Press\nER  -\n",
    "warnings": []
  },
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0,
    "total_tokens": 0,
    "estimated_cost_usd": 0,
    "usage_estimated": false,
    "cached": false,
    "provider": "self_hosted",
    "model": "citation.js_0.9.0"
  },
  "input_words": 3,
  "output_words": 8
}

Errors: cause and fix

Every error uses this JSON shape and a link to its exact fix:

{
  "error": {
    "code": "unauthorized",
    "message": "A valid API key is required.",
    "docs_url": "https://metaphrase.msalman.com/docs/errors#unauthorized"
  }
}
CodeHTTPCauseFix
invalid_request400Check the request fields and their allowed values.Send the documented JSON fields with the correct types. Unknown fields are rejected.
invalid_json400The request body is not valid JSON.Serialize the request with JSON.stringify or your language's JSON encoder.
unsupported_media_type415Send application/json content.Set Content-Type: application/json. File uploads use their separate documented route.
body_too_large413The request body exceeds the allowed size.Reduce the payload and split long documents at sentence boundaries.
text_too_long413The text exceeds the configured character limit.Use the max_input_chars value in the API specification and split longer documents.
unauthorized401A valid API key is required.Send Authorization: Bearer YOUR_KEY. Create a new key if the old one was revoked.
forbidden403This action is not available to this account.Check account status and the key's access permissions.
rate_limited429Too many requests. Please wait and try again.Wait for Retry-After seconds and use exponential backoff with jitter.
quota_exceeded429The monthly usage quota has been reached.Wait for the next UTC calendar month or ask an administrator to change the plan.
service_unavailable503A required service is temporarily unavailable.Wait and retry. The operator should check Redis, PostgreSQL, or the tool's health.
not_found404This resource does not exist.Check the API version, endpoint name, and resource identifier.
method_not_allowed405This HTTP method is not supported.Use POST for processing endpoints and the method documented for dashboard routes.
internal_error500The request could not be completed.Retry once. If it persists, provide the X-Request-Id header to the operator.
invalid_source422The source could not be used.Check the DOI, ISBN, or public HTTP URL, or use manual citation fields.
source_unavailable422Source metadata could not be retrieved.Try a DOI or ISBN, or enter the source details manually.

For streaming requests, failures after HTTP headers are sent arrive as an SSE error event with this same error object. Never treat partial text as a completed result or append output from a retry.

Rate limits and quotas

Defaults: Free 15 requests per 60 seconds and 500 accepted calls per key per UTC calendar month; Pro placeholders 120/60 seconds and 25,000/month. The operator can change plans; response headers are authoritative. Calls to all tools share a key's limits. Accepted cache hits and upstream failures consume quota. Authentication/schema failures and provider-not-configured preflight failures do not. X-RateLimit-Remaining, X-RateLimit-Reset, X-Quota-Remaining and X-Quota-Reset show remaining capacity and Unix-second reset times. For HTTP 429 wait Retry-After seconds; quota/budget limits need a reset or operator action. Requests may also receive 429 when the shared processing slots are busy. See retries and long texts.

Code samples

Complete backend programs. Set METAPHRASE_API_KEY in your server environment; never expose it in a frontend.

request.sh
#!/usr/bin/env bash
set -euo pipefail
: "${METAPHRASE_API_KEY:?Set METAPHRASE_API_KEY in your backend environment}"
BASE_URL="${METAPHRASE_BASE_URL:-https://metaphrase.msalman.com}"
curl --fail-with-body --silent --show-error \
  --request POST "${BASE_URL%/}/api/v1/cite" \
  --header "Authorization: Bearer $METAPHRASE_API_KEY" \
  --header 'Content-Type: application/json' \
  --data-binary @- <<'JSON'
{
  "source_type": "manual",
  "style": "apa",
  "fields": {
    "type": "book",
    "title": "A clear idea",
    "authors": [
      {
        "given": "Ada",
        "family": "Lovelace"
      }
    ],
    "year": 2024,
    "publisher": "Example Press"
  },
  "stream": false
}
JSON

Run: bash request.sh

Try the API with Scalar

Explore the schema and send a real request. Enter your key only in this playground.