Skip to content

Connect to VerseDB

Lets a third-party site get a read-only token for a member's account without the member copying one by hand. It is an OAuth 2.0 authorization-code flow with PKCE (S256).

  1. Generate a random code_verifier (43-128 characters) and a state, and keep both on your server. The code_challenge is the base64url-encoded SHA-256 of the verifier, without padding.
  2. Send the member to https://versedb.com/connect with redirect_uri, state, code_challenge, code_challenge_method=S256, and optionally client_name (your app, such as WordPress, 40 characters at most), site_name (100 at most) and scope (a space-separated subset of read:public read:showcase; both by default). redirect_uri must be HTTPS, or http://localhost while developing.
  3. The member signs in if needed and approves or denies. VerseDB redirects to redirect_uri with code and state, or with error=access_denied and state when they deny. Check that state matches.
  4. Within 5 minutes, exchange the code here from your server.

The token is named "{client_name}: {your host}", lasts 365 days, shows in the member's My Apps page and counts toward their limit of 10 active tokens. Connecting the same site again replaces its previous token. read:showcase reads the member's profile, collection, wishlist, pull list and reading progress for display, without email, birth date, location, prices, notes, storage or loans.

Exchange a Connect code for a token

POST/api/v1/connect/token
No token needed

Redeems the single-use code from the Connect redirect. A code works once: a second attempt, a wrong code_verifier or a different redirect_uri fails and the code cannot be used again.

Request body application/json

grant_typestringrequired

Must be authorization_code.

Example: "authorization_code"

codestringrequired

The code from the redirect.

Example: "9Qm2cT4xZ7bN1pL8vR3kW6yH0sD5fJ2aG4eU7iO1nB3vC6xZ"

redirect_uristringrequired

Exactly the redirect_uri sent to /connect.

Example: "https://example.com/wp-admin/options-general.php?page=versedb"

code_verifierstringrequired

The verifier the code_challenge was made from.

Example: "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

Responses

200

Success.

Headers: X-RateLimit-Limit, X-RateLimit-Remaining

access_tokenstringrequired

Example: "Sq2mX9p..."

token_typestringrequired

Example: "Bearer"

expires_atstringrequired

Example: "2027-09-29T15:00:00Z"

abilitiesarray of stringsrequired

Example: ["read:public","read:showcase"]

400

The request could not be processed: an OAuth error and its description.

errorstringrequired

unsupported_grant_type, invalid_request or invalid_grant.

Example: "invalid_grant"

error_descriptionstringrequired

Example: "This code is invalid or has expired."

Example body, from the documented examples

{
  "error": "invalid_grant",
  "error_description": "This code is invalid or has expired."
}
429

Rate limit exceeded. This endpoint allows 30 requests a minute from one address, and 500 a day from one address for one redirect_uri host. Wait for the number of seconds in the Retry-After header before retrying.

Headers: Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining

messagestringrequired

Example: "Too Many Attempts."

Example body, from the documented examples

{
  "message": "Too Many Attempts."
}

Example request

curl --request POST \
  'https://versedb.com/api/v1/connect/token' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
  "grant_type": "authorization_code",
  "code": "9Qm2cT4xZ7bN1pL8vR3kW6yH0sD5fJ2aG4eU7iO1nB3vC6xZ",
  "redirect_uri": "https://example.com/wp-admin/options-general.php?page=versedb",
  "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
}'

Example response 200

{
  "access_token": "Sq2mX9p...",
  "token_type": "Bearer",
  "expires_at": "2027-09-29T15:00:00Z",
  "abilities": [
    "read:public",
    "read:showcase"
  ]
}

Response headers

X-RateLimit-Limitinteger

Requests allowed in the current window.

X-RateLimit-Remaininginteger

Requests remaining in the current window.

Retry-Afterinteger

Seconds to wait before retrying.