Documentation / API · Authentication / Start sign-in, registration or identity linking POST Start sign-in, registration or identity linking/api/v1/auth/oauth/{provider}/start
login, register and link have separate intent. Registration requires the gate and current legal acceptance. Linking requires a browser session and later a fresh action code. Browser cookie, state and PKCE bind the flow for ten minutes.
On this page Access and permissions Parameters and headers Request body Responses Retries and asynchronous work Request examples Related guides login, register and link have separate intent. Registration requires the gate and current legal acceptance. Linking requires a browser session and later a fresh action code. Browser cookie, state and PKCE bind the flow for ten minutes.
No account sign-in is required. Any listed browser-origin checks and rate limits still apply.
json Copy example
{
"link" : {
"browser_session" : true ,
"csrf" : true
},
"login" : {
"browser_origin" : true
},
"register" : {
"browser_origin" : true ,
"legal_acceptance" : true ,
"registration_gate" : true
}
} Field Location Type and limits Required Meaning provider Path string; {"enum":["google","github"]} Yes Supported login provider: google or github. Origin Header string; {"format":"uri"} Yes The same HTTPS origin as the public browser site. Required for browser login and provider-start requests.
Field Type and limits Required Meaning $ object; {"additionalProperties":false} Yes — $.intent string; {"enum":["login","register","link"]} Yes Requested provider flow: login, registration or linking an identity to the current account. $.legal_acceptance LegalAcceptance No — $.legal_acceptance.privacy_acknowledged boolean; {"const":true} Yes Must be true when acknowledgement of privacy information is required. $.legal_acceptance.privacy_version string; {"pattern":"^[0-9a-f]{64}$"} Yes SHA-256 version returned for the currently published privacy text. $.legal_acceptance.terms_accepted boolean; {"const":true} Yes Must be true when legal acceptance is required. $.legal_acceptance.terms_version string; {"pattern":"^[0-9a-f]{64}$"} Yes SHA-256 version returned for the currently published terms. Retrieve the current text before accepting. $.return_to string; {"default":"/app"} No Allowed local destination after sign-in. External and unsafe destinations are rejected. $ (allOf 1) JSON No —
200 · Successful response. Header Type and limits Meaning Cache-Control string; {"pattern":"(?:^|,\\s*)no-store(?:,|$)"} Private API responses prohibit storage. Public OAuth metadata is cached for 300 seconds; live streams additionally prohibit transformation. Content-Language string; {"enum":["en","de"]} Language of human-readable response text, resolved from Accept-Language or the documented browser preference. Technical codes and identifiers remain stable. Referrer-Policy JSON; {"enum":["strict-origin-when-cross-origin","no-referrer"]} The default referrer policy is strict-origin-when-cross-origin. Provider-login responses use no-referrer to protect login parameters. Vary string Responses vary by Accept-Language; browser-rendered responses can also vary by the preference cookie. X-Content-Type-Options JSON; {"const":"nosniff"} The browser must use the declared content type. X-Frame-Options JSON; {"const":"DENY"} The response must not be embedded in a frame. X-Request-ID string Server-generated request identifier. Include this when reporting an error; inbound values are not trusted.
application/json
Field Type and limits Required Meaning $ object Yes — $.authorization_url string Yes —
json Copy example
{
"authorization_url" : "demo"
} 401 · Request rejected. Inspect the stable problem code. Stable error codes unauthorized
Header Type and limits Meaning Cache-Control string; {"pattern":"(?:^|,\\s*)no-store(?:,|$)"} Private API responses prohibit storage. Public OAuth metadata is cached for 300 seconds; live streams additionally prohibit transformation. Content-Language string; {"enum":["en","de"]} Language of human-readable response text, resolved from Accept-Language or the documented browser preference. Technical codes and identifiers remain stable. Referrer-Policy JSON; {"enum":["strict-origin-when-cross-origin","no-referrer"]} The default referrer policy is strict-origin-when-cross-origin. Provider-login responses use no-referrer to protect login parameters. Vary string Responses vary by Accept-Language; browser-rendered responses can also vary by the preference cookie. X-Content-Type-Options JSON; {"const":"nosniff"} The browser must use the declared content type. X-Frame-Options JSON; {"const":"DENY"} The response must not be embedded in a frame. X-Request-ID string Server-generated request identifier. Include this when reporting an error; inbound values are not trusted.
application/problem+json
Field Type and limits Required Meaning $ Problem Yes — $.code string Yes Stable machine-readable error code $.detail string Yes Short localized explanation without internal error details $.instance string Yes Unique relative identifier /api/v1/requests/{request_id}; not a retrievable resource $.message string Yes Temporarily identical to detail for existing clients $.message_key string Yes Stable translation key for changing the displayed language without another request $.message_params object; {"additionalProperties":true} Yes Named, safely rendered message parameters; never arbitrary HTML $.request_id string; {"pattern":"^[0-9a-f]{32}$"} Yes Server-generated diagnostic identifier. It contains no login token or credential. $.status integer; {"maximum":599,"minimum":400} Yes — $.title string Yes Localized HTTP status title $.type string; {"const":"about:blank"} Yes —
json Copy example
{
"code" : "demo" ,
"detail" : "Demo error detail; inspect the documented code." ,
"instance" : "demo" ,
"message" : "Demo error detail; inspect the documented code." ,
"message_key" : "errors.requestFailed" ,
"message_params" : {},
"request_id" : "00000000000000000000000000000000" ,
"status" : 401,
"title" : "Demo error" ,
"type" : "about:blank"
} 403 · Request rejected. Inspect the stable problem code. Stable error codes browser_required invalid_origin
Header Type and limits Meaning Cache-Control string; {"pattern":"(?:^|,\\s*)no-store(?:,|$)"} Private API responses prohibit storage. Public OAuth metadata is cached for 300 seconds; live streams additionally prohibit transformation. Content-Language string; {"enum":["en","de"]} Language of human-readable response text, resolved from Accept-Language or the documented browser preference. Technical codes and identifiers remain stable. Referrer-Policy JSON; {"enum":["strict-origin-when-cross-origin","no-referrer"]} The default referrer policy is strict-origin-when-cross-origin. Provider-login responses use no-referrer to protect login parameters. Vary string Responses vary by Accept-Language; browser-rendered responses can also vary by the preference cookie. X-Content-Type-Options JSON; {"const":"nosniff"} The browser must use the declared content type. X-Frame-Options JSON; {"const":"DENY"} The response must not be embedded in a frame. X-Request-ID string Server-generated request identifier. Include this when reporting an error; inbound values are not trusted.
application/problem+json
Field Type and limits Required Meaning $ Problem Yes — $.code string Yes Stable machine-readable error code $.detail string Yes Short localized explanation without internal error details $.instance string Yes Unique relative identifier /api/v1/requests/{request_id}; not a retrievable resource $.message string Yes Temporarily identical to detail for existing clients $.message_key string Yes Stable translation key for changing the displayed language without another request $.message_params object; {"additionalProperties":true} Yes Named, safely rendered message parameters; never arbitrary HTML $.request_id string; {"pattern":"^[0-9a-f]{32}$"} Yes Server-generated diagnostic identifier. It contains no login token or credential. $.status integer; {"maximum":599,"minimum":400} Yes — $.title string Yes Localized HTTP status title $.type string; {"const":"about:blank"} Yes —
json Copy example
{
"code" : "demo" ,
"detail" : "Demo error detail; inspect the documented code." ,
"instance" : "demo" ,
"message" : "Demo error detail; inspect the documented code." ,
"message_key" : "errors.requestFailed" ,
"message_params" : {},
"request_id" : "00000000000000000000000000000000" ,
"status" : 403,
"title" : "Demo error" ,
"type" : "about:blank"
} 422 · Request rejected. Inspect the stable problem code. Stable error codes invalid_input invalid_request invalid_return_to
Header Type and limits Meaning Cache-Control string; {"pattern":"(?:^|,\\s*)no-store(?:,|$)"} Private API responses prohibit storage. Public OAuth metadata is cached for 300 seconds; live streams additionally prohibit transformation. Content-Language string; {"enum":["en","de"]} Language of human-readable response text, resolved from Accept-Language or the documented browser preference. Technical codes and identifiers remain stable. Referrer-Policy JSON; {"enum":["strict-origin-when-cross-origin","no-referrer"]} The default referrer policy is strict-origin-when-cross-origin. Provider-login responses use no-referrer to protect login parameters. Vary string Responses vary by Accept-Language; browser-rendered responses can also vary by the preference cookie. X-Content-Type-Options JSON; {"const":"nosniff"} The browser must use the declared content type. X-Frame-Options JSON; {"const":"DENY"} The response must not be embedded in a frame. X-Request-ID string Server-generated request identifier. Include this when reporting an error; inbound values are not trusted.
application/problem+json
Field Type and limits Required Meaning $ Problem Yes — $.code string Yes Stable machine-readable error code $.detail string Yes Short localized explanation without internal error details $.instance string Yes Unique relative identifier /api/v1/requests/{request_id}; not a retrievable resource $.message string Yes Temporarily identical to detail for existing clients $.message_key string Yes Stable translation key for changing the displayed language without another request $.message_params object; {"additionalProperties":true} Yes Named, safely rendered message parameters; never arbitrary HTML $.request_id string; {"pattern":"^[0-9a-f]{32}$"} Yes Server-generated diagnostic identifier. It contains no login token or credential. $.status integer; {"maximum":599,"minimum":400} Yes — $.title string Yes Localized HTTP status title $.type string; {"const":"about:blank"} Yes —
json Copy example
{
"code" : "demo" ,
"detail" : "Demo error detail; inspect the documented code." ,
"instance" : "demo" ,
"message" : "Demo error detail; inspect the documented code." ,
"message_key" : "errors.requestFailed" ,
"message_params" : {},
"request_id" : "00000000000000000000000000000000" ,
"status" : 422,
"title" : "Demo error" ,
"type" : "about:blank"
} 429 · Request rejected. Inspect the stable problem code. Stable error codes rate_limited
Header Type and limits Meaning Cache-Control string; {"pattern":"(?:^|,\\s*)no-store(?:,|$)"} Private API responses prohibit storage. Public OAuth metadata is cached for 300 seconds; live streams additionally prohibit transformation. Content-Language string; {"enum":["en","de"]} Language of human-readable response text, resolved from Accept-Language or the documented browser preference. Technical codes and identifiers remain stable. Referrer-Policy JSON; {"enum":["strict-origin-when-cross-origin","no-referrer"]} The default referrer policy is strict-origin-when-cross-origin. Provider-login responses use no-referrer to protect login parameters. Retry-After string; {"pattern":"^[0-9]+$"} Seconds before retry. Preserve supported idempotency identifiers and respect the operation’s mutation semantics. Vary string Responses vary by Accept-Language; browser-rendered responses can also vary by the preference cookie. X-Content-Type-Options JSON; {"const":"nosniff"} The browser must use the declared content type. X-Frame-Options JSON; {"const":"DENY"} The response must not be embedded in a frame. X-Request-ID string Server-generated request identifier. Include this when reporting an error; inbound values are not trusted.
application/problem+json
Field Type and limits Required Meaning $ Problem Yes — $.code string Yes Stable machine-readable error code $.detail string Yes Short localized explanation without internal error details $.instance string Yes Unique relative identifier /api/v1/requests/{request_id}; not a retrievable resource $.message string Yes Temporarily identical to detail for existing clients $.message_key string Yes Stable translation key for changing the displayed language without another request $.message_params object; {"additionalProperties":true} Yes Named, safely rendered message parameters; never arbitrary HTML $.request_id string; {"pattern":"^[0-9a-f]{32}$"} Yes Server-generated diagnostic identifier. It contains no login token or credential. $.status integer; {"maximum":599,"minimum":400} Yes — $.title string Yes Localized HTTP status title $.type string; {"const":"about:blank"} Yes —
json Copy example
{
"code" : "demo" ,
"detail" : "Demo error detail; inspect the documented code." ,
"instance" : "demo" ,
"message" : "Demo error detail; inspect the documented code." ,
"message_key" : "errors.requestFailed" ,
"message_params" : {},
"request_id" : "00000000000000000000000000000000" ,
"status" : 429,
"title" : "Demo error" ,
"type" : "about:blank"
} 503 · Request rejected. Inspect the stable problem code. Stable error codes provider_unavailable registration_unavailable unavailable
Header Type and limits Meaning Cache-Control string; {"pattern":"(?:^|,\\s*)no-store(?:,|$)"} Private API responses prohibit storage. Public OAuth metadata is cached for 300 seconds; live streams additionally prohibit transformation. Content-Language string; {"enum":["en","de"]} Language of human-readable response text, resolved from Accept-Language or the documented browser preference. Technical codes and identifiers remain stable. Referrer-Policy JSON; {"enum":["strict-origin-when-cross-origin","no-referrer"]} The default referrer policy is strict-origin-when-cross-origin. Provider-login responses use no-referrer to protect login parameters. Retry-After string; {"pattern":"^[0-9]+$"} Seconds before retry. Preserve supported idempotency identifiers and respect the operation’s mutation semantics. Vary string Responses vary by Accept-Language; browser-rendered responses can also vary by the preference cookie. X-Content-Type-Options JSON; {"const":"nosniff"} The browser must use the declared content type. X-Frame-Options JSON; {"const":"DENY"} The response must not be embedded in a frame. X-Request-ID string Server-generated request identifier. Include this when reporting an error; inbound values are not trusted.
application/problem+json
Field Type and limits Required Meaning $ Problem Yes — $.code string Yes Stable machine-readable error code $.detail string Yes Short localized explanation without internal error details $.instance string Yes Unique relative identifier /api/v1/requests/{request_id}; not a retrievable resource $.message string Yes Temporarily identical to detail for existing clients $.message_key string Yes Stable translation key for changing the displayed language without another request $.message_params object; {"additionalProperties":true} Yes Named, safely rendered message parameters; never arbitrary HTML $.request_id string; {"pattern":"^[0-9a-f]{32}$"} Yes Server-generated diagnostic identifier. It contains no login token or credential. $.status integer; {"maximum":599,"minimum":400} Yes — $.title string Yes Localized HTTP status title $.type string; {"const":"about:blank"} Yes —
json Copy example
{
"code" : "demo" ,
"detail" : "Demo error detail; inspect the documented code." ,
"instance" : "demo" ,
"message" : "Demo error detail; inspect the documented code." ,
"message_key" : "errors.requestFailed" ,
"message_params" : {},
"request_id" : "00000000000000000000000000000000" ,
"status" : 503,
"title" : "Demo error" ,
"type" : "about:blank"
} This change does not have a general retry guarantee. If the response is unclear, read the affected resource before trying again. Follow Retry-After waiting times and request new sign-in or action codes when they expire.
Replace demo IDs, timestamps and placeholders with your own values. For a retry, keep the same IDs, time and content. These examples do not run requests on this page.
Keep login links, codes, cookies and keys private. Do not print them in logs or share them in support requests.
shell Copy example
curl --silent --show-error --output /dev/ null --write-out "%{http_code}\n" \
--request POST \
--header "Origin: https://metribeacon.com" \
--header "Content-Type: application/json" \
--data-binary '{"intent":"login"}' \
"https://metribeacon.com/api/v1/auth/oauth/google/start"
python Copy example
import json
from pathlib import Path
from urllib.request import Request, HTTPRedirectHandler, build_opener
from urllib.error import HTTPError
headers = {}
headers[ "Origin" ] = "https://metribeacon.com"
headers[ "Content-Type" ] = "application/json"
request = Request( "https://metribeacon.com/api/v1/auth/oauth/google/start" , data= "{\"intent\":\"login\"}" .encode( "utf-8" ), headers=headers, method= "POST" )
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, request, fp, code, message, headers, target):
return None
opener = build_opener(NoRedirect())
try:
with opener.open(request, timeout=10) as response:
print(response.status)
except HTTPError as error:
print(error.code)
error.close()
javascript Copy example
import { readFile } from "node:fs/promises" ;
import { homedir } from "node:os" ;
import { join } from "node:path" ;
const headers = {};
headers[ "Origin" ] = "https://metribeacon.com" ;
headers[ "Content-Type" ] = "application/json" ;
const response = await fetch( "https://metribeacon.com/api/v1/auth/oauth/google/start" , {
method: "POST" , headers, redirect: "manual" ,
signal: AbortSignal.timeout(10000), body: "{\"intent\":\"login\"}" ,
});
console.log(response.status);
await response.body?.cancel();
go Copy example
package main
import (
"fmt"
"net/http"
"time"
"strings"
)
func main() {
request, err := http.NewRequest( "POST" , "https://metribeacon.com/api/v1/auth/oauth/google/start" , strings.NewReader( "{\"intent\":\"login\"}" ))
if err != nil { panic( "request failed; credentials and response omitted" ) }
request.Header.Set( "Origin" , "https://metribeacon.com" )
request.Header.Set( "Content-Type" , "application/json" )
client := &http.Client{Timeout: 10*time.Second, CheckRedirect: func (*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
response, err := client.Do(request)
if err != nil { panic( "request failed; credentials and response omitted" ) }
defer response.Body.Close()
fmt.Println(response.StatusCode)
}
Related guides HTTP API, OAuth and MCP Find the user API endpoints, their permissions, fields, examples and response formats.
GET Confirm a provider callback in the original browserThe callback verifies browser binding, state, PKCE and provider identity. Tokens are not placed in the redirect URL. Existing mail accounts require explicit linking rather than automatic matching.
POST Request a code for one sensitive actionRequest a six-digit confirmation code for a sensitive account or workspace change. It lasts five minutes and allows five incorrect attempts. Use the same signed-in browser, action, target and parameters when confirming. A replacement requested after 60 seconds invalidates the previous code for that action. For your own account use link_identity, unlink_identity, add_passkey, remove_passkey or delete_self; workspace membership actions require owner permission. Do not use sign-in codes to confirm changes.
DELETE Cancel your pending action confirmationOnly an outstanding confirmation belonging to the current account and session can be cancelled.