Get the protected-resource metadata
GET /.well-known/oauth-protected-resource/2026-05
Description
Returns the OAuth metadata for this API: the resource identifier to request a
token for, the authorization server that issues it, the scope to ask for, and
how to present the token. The document follows RFC 9728, so a standard OAuth
client library can read it without custom code. It's public: the request needs
no token and no AndOpen-API-Version header, because a client reads it before
it holds either.
When to use
Reach for this endpoint when you're building a partner app that connects to
&Open accounts with OAuth. Read it once at the start of the authorization flow
and use its values for the resource and scope you send to the authorization
server, rather than hard-coding them per region. The partner OAuth flow itself
is described in OAuth.
You don't need to know this URL in advance. Any request the API rejects with a
401 carries it in the WWW-Authenticate header, as resource_metadata.
If you authenticate with an API key, you don't need this endpoint.
Parameters
This endpoint takes no parameters, no request body, and no headers. Each region and environment serves its own document from its own base URL, as listed in Environments:
| Environment | Metadata URL |
|---|---|
| US / Global | https://api.andopen.co/.well-known/oauth-protected-resource/2026-05 |
| EU | https://api.eu.andopen.co/.well-known/oauth-protected-resource/2026-05 |
Staging serves its own document in the same way, from the staging base URL.
The path is the API's resource identifier with
/.well-known/oauth-protected-resource inserted after the host, as RFC 9728
describes, so a client that holds only the resource identifier can derive it.
Worked examples
A plain GET, with no headers. The JavaScript, Python, and Ruby versions read
the resource identifier and the authorization server off the document.
- cURL
- JavaScript
- Python
- Ruby
curl https://api.andopen.co/.well-known/oauth-protected-resource/2026-05
const response = await fetch(
"https://api.andopen.co/.well-known/oauth-protected-resource/2026-05",
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const metadata = await response.json();
console.log(metadata.resource, metadata.authorization_servers[0]);
import requests
response = requests.get(
"https://api.andopen.co/.well-known/oauth-protected-resource/2026-05",
)
response.raise_for_status()
metadata = response.json()
print(metadata["resource"], metadata["authorization_servers"][0])
require "net/http"
require "json"
uri = URI("https://api.andopen.co/.well-known/oauth-protected-resource/2026-05")
response = Net::HTTP.get_response(uri)
response.value # raises on a non-2xx response
metadata = JSON.parse(response.body)
puts "#{metadata['resource']} #{metadata['authorization_servers'].first}"
Response shape
A successful call returns 200 OK with the metadata document as a flat JSON
object.
| Field | Description |
|---|---|
resource (string · uri · required) | The resource identifier for this API in this region. Send it as the resource parameter when you request a token. A token issued for a resource this API doesn't accept is rejected with invalid_audience. |
authorization_servers (array · required) | The authorization server that issues tokens for this API. Read its own endpoints from its RFC 8414 metadata, at /.well-known/oauth-authorization-server on that host. |
scopes_supported (array · optional) | The scope to request. Today that's gifting:write alone. |
bearer_methods_supported (array · optional) | How to present the token: in the Authorization header only, never as a query parameter. |
{
"resource": "https://api.andopen.co/2026-05",
"authorization_servers": ["https://auth.andopen.co"],
"scopes_supported": ["gifting:write"],
"bearer_methods_supported": ["header"]
}
Per-field notes
resourcediffers by region, and a token from one region isn't accepted in the other, so a partner app that serves accounts in both regions reads the document from each.resourceincludes the API version,2026-05. It's an identifier, not a base URL, so don't send API requests to it.
Error cases
This endpoint is public and takes no input, so it has no request to reject. It
can still return a 5xx status when something fails on our side; retry after a
short delay.