Open API v1
Quickstart
This guide covers the Open API v1 OAuth flow. Request app access first, then use your integration settings to complete registration, authorization and an API call.
Request access1 · Register your client
Register once per origin. Redirect URIs must be https (localhost is allowed in development) and must not contain a fragment. Persist the returned client_id.
POST https://api.harperharbor.com/oauth/register Content-Type: application/json { "client_name": "Your app", "redirect_uris": ["https://app.example.com/oauth/callback"], "grant_types": ["authorization_code", "refresh_token"] } → 201 { "client_id": "…" }2 · Ask the user to authorize
Authorization code with PKCE (S256). Include the resource indicator so the token is bound to the Open API audience.
https://api.harperharbor.com/oauth/authorize ?response_type=code &client_id=… &redirect_uri=https://app.example.com/oauth/callback &resource=https://api.harperharbor.com/open/v1 &state=… &code_challenge=… # base64url(sha256(verifier)) &code_challenge_method=S2563 · Exchange the code
Post the code and verifier to the token endpoint. You receive an access token and a refresh token.
POST https://api.harperharbor.com/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=…&client_id=… &redirect_uri=…&code_verifier=…&resource=https://api.harperharbor.com/open/v1 → 200 { "access_token": "…", "refresh_token": "…", "expires_in": 3600 }4 · Make the first call
Use a Bearer token in the Authorization header and include the language header. Responses use public numeric user IDs, without internal account identifiers.
GET https://api.harperharbor.com/open/v1/me Authorization: Bearer <access token> language: en → 200 { "id": 100001, "nickname": "Aoi" }
Request headers
| Authorization | Bearer <access token> |
| language | zh-Hant · zh-Hans · en · ja · ko |
| from | web (optional) |
Errors
JSON errors include a code, a message and a retryable flag. For a 401, try refreshing the token. If authentication still fails, ask the user to authorize again.
{ "error": "unauthorized | forbidden | not_found | internal",
"message": "…",
"retryable": true }Quotas
Each app has a daily points quota to limit usage. There is no extra charge for the quota. View usage by app, service and lane in the developer console.