Portal ¶
portal¶
POST /api/v1/portal/sessions¶
Create Portal Session
Description
Mint a portal deep-link URL for a 3rd-party app (plan 016). The app authenticates with its own client credentials in the body; SweatStack stamps the authenticated app id into the returned URL as the brand context. Server-to-server (no user token); the user is identified at open time when they land on the portal page and sign in.
This is the construction boundary: integrators only ever see the
returned url, so the portal URL shape stays an internal detail we
can evolve (e.g. to opaque tokens) without changing this contract.
Request body
{
"client_id": "string",
"client_secret": null,
"destination": "manage-teams",
"return_url": null
}
Schema of the request body
{
"properties": {
"client_id": {
"type": "string",
"title": "Client Id"
},
"client_secret": {
"anyOf": [
{
"type": "string",
"format": "password",
"writeOnly": true
},
{
"type": "null"
}
],
"title": "Client Secret"
},
"destination": {
"$ref": "#/components/schemas/PortalDestination"
},
"return_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Return Url"
}
},
"type": "object",
"required": [
"client_id",
"destination"
],
"title": "PortalSessionRequest",
"description": "Request body for POST /api/v1/portal/sessions. A 3rd-party app\nauthenticates with its own client credentials and asks SweatStack to\nmint a portal deep-link for a given destination. SweatStack stamps the\nauthenticated app id into the returned URL, so the brand context is\nestablished by authentication, not by a client-supplied parameter.\nSee plan 016.\n\n`client_secret` is optional: a public client (PKCE, no registered\nsecret) authenticates with `client_id` alone, mirroring the token\nendpoint's public/confidential split that\n/.well-known/openid-configuration already advertises. An app that HAS\nregistered a secret must still present it. See\n`Logic.create_portal_session` (plan 045)."
}
Responses
{
"url": "string"
}
Schema of the response body
{
"properties": {
"url": {
"type": "string",
"title": "Url"
}
},
"type": "object",
"required": [
"url"
],
"title": "PortalSessionResponse"
}
{
"detail": [
{
"loc": [
null
],
"msg": "string",
"type": "string"
}
]
}
Schema of the response body
{
"properties": {
"detail": {
"items": {
"$ref": "#/components/schemas/ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}
Schemas¶
HTTPValidationError¶
| Name | Type | Description |
|---|---|---|
detail |
Array<ValidationError> |
PortalDestination¶
Type: string
PortalSessionRequest¶
| Name | Type | Description |
|---|---|---|
client_id |
string | |
client_secret |
||
destination |
PortalDestination | |
return_url |
PortalSessionResponse¶
| Name | Type | Description |
|---|---|---|
url |
string |
ValidationError¶
| Name | Type | Description |
|---|---|---|
loc |
Array<> | |
msg |
string | |
type |
string |
Security schemes¶
| Name | Type | Scheme | Description |
|---|---|---|---|
| HTTPBearer | http | bearer | |
| HTTPBasic | http | basic |