Autenticación

Obtener una clave de API

Cada llamada lleva un token Bearer en la cabecera Authorization. Sofia vuelve a leer los derechos que hay detrás en cada llamada: una persona retirada de un Workspace, o una autorización revocada, detiene el token en la siguiente petición.

MétodoParaToken
Clave personalAutomatizar tu propia cuenta, scripts, agentessofia_pk_live_…, válido hasta su caducidad
OAuth, código de autorización + PKCEUn producto que actúa por sus usuarios, en el Workspace que cada uno eligesofia_live_at_…, una hora, renovable
OAuth, client credentialsUn servidor tuyo que automatiza un Workspace de tu propiedadsofia_live_at_…, una hora

Claves personales

Crea una clave en Ajustes › API › Acceso personal. Actúa por ti en todos tus Workspaces: el establecimiento que indiques fija el Workspace, y tu rol en él decide lo que la clave puede hacer.

bash
curl https://api.sofia-post.com/api/v1/establishments \
  -H "Authorization: Bearer sofia_pk_live_…"

OAuth: código de autorización con PKCE

Registra un cliente en Ajustes › API › Clientes de aplicación: su nombre, su logotipo, su política de privacidad, los permisos que puede pedir y sus URL de redirección https. Un cliente confidencial tiene un secreto; un cliente público (app móvil, extensión de navegador) no lo tiene y se apoya solo en PKCE.

Envía a la persona al endpoint de autorización con un challenge PKCE (S256 es obligatorio) y un state que guardes en su sesión:

javascript
import { createHash, randomBytes } from 'node:crypto';

const verifier = randomBytes(32).toString('base64url');
const challenge = createHash('sha256').update(verifier).digest('base64url');
const state = randomBytes(16).toString('base64url');

const url = new URL('https://api.sofia-post.com/api/v1/oauth/authorize');
url.search = new URLSearchParams({
  response_type: 'code',
  client_id: process.env.SOFIA_CLIENT_ID,
  redirect_uri: 'https://app.example.com/oauth/callback',
  scope: 'establishments:read posts:read posts:write offline_access',
  state,
  code_challenge: challenge,
  code_challenge_method: 'S256',
}).toString();

La persona inicia sesión en Sofia, ve tu nombre, tu logotipo y tus permisos, elige un Workspace y acepta. Sofia la devuelve entonces a tu URL de redirección con un code, tu state y el emisor iss. Comprueba ambos y luego canjea el código:

bash
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
  -u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
  -d grant_type=authorization_code \
  -d code=$CODE \
  -d redirect_uri=https://app.example.com/oauth/callback \
  -d code_verifier=$VERIFIER
json
{
  "access_token": "sofia_live_at_…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "establishments:read posts:read posts:write offline_access",
  "refresh_token": "sofia_live_rt_…"
}
  • El código es válido 5 minutos, una sola vez. Si se reutiliza, se rechaza y los tokens que dio dejan de funcionar.
  • El token de acceso dura una hora y actúa solo en el Workspace que eligió la persona.
  • Un refresh_token solo se devuelve si pediste offline_access. Es de un solo uso: guarda el nuevo cada vez. Reutilizar un refresh token ya usado revoca toda la autorización.
bash
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
  -u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
  -d grant_type=refresh_token \
  -d refresh_token=$REFRESH_TOKEN

OAuth: client credentials

Un cliente confidencial también puede actuar en un Workspace que pertenezca a su propietario, sin una persona en el circuito. Cuando el cliente tiene varios Workspaces, indica uno con workspace_id.

bash
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
  -u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
  -d grant_type=client_credentials \
  -d workspace_id=$WORKSPACE_ID

Permisos (scopes)

ScopePermite
establishments:readListar establecimientos
accounts:read, accounts:writeLeer las redes conectadas; crear enlaces de conexión
media:read, media:writeLeer la biblioteca de medios; subir e importar medios
posts:read, posts:writeListar y seguir publicaciones; publicarlas, editarlas y eliminarlas
insights:readLeer estadísticas
webhooks:read, webhooks:writeListar webhooks; registrarlos, probarlos y eliminarlos
offline_accessSolo OAuth: recibir un refresh token

Una llamada sin el scope necesario responde 403 insufficient_scope. Los metadatos del servidor (RFC 8414) enumeran cada endpoint y cada scope:

text
https://api.sofia-post.com/.well-known/oauth-authorization-server/api/v1/oauth