Organizaciones, proyectos, miembros e invitaciones
Una organización es quien paga y quien puede hacer qué. Contiene proyectos, y los proyectos contienen lo que compras. Esta guía muestra las llamadas del día a día para montar una y para llevar un equipo. Los ejemplos usan el ayudante de Usar la API de Zaroz.
Roles
Rol
Puede
owner
Todo, incluido borrar la organización y gestionar a otros propietarios
admin
Comprar, gestionar proyectos y miembros (no por encima de su propio rol), crear tokens de API de la organización
billing
Pagar facturas y leer la facturación
member
Usar los servicios de la organización; ver sus proyectos, miembros y facturas
Dos reglas te protegen de quedarte fuera: no puedes degradar ni quitar al último propietario, y no puedes cambiar a un miembro cuyo rol esté por encima del tuyo (403 member-outranks-caller). Cualquiera puede quitarse a sí mismo. Una organización personal (toda cuenta tiene una) no admite otros miembros: añadir uno responde 422 member-personal-organization.
Te conviertes en su propietario. GET /organizations lista todas las organizaciones a las que perteneces y GET /organizations/by-slug/{slug} busca una por su slug. PATCH /organizations/{id} la renombra.
Proyectos
Un proyecto agrupa servicios. El slug es único dentro de la organización.
curl
Code
curl -sS -X POST "$ZAROZ_API/organizations/$ORG/projects" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"name": "Production", "slug": "production", "description": "Servidores en vivo"}'curl -sS -X PATCH "$ZAROZ_API/projects/$PROJECT" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"description": null}' # null lo borra; los campos omitidos no cambiancurl -sS "$ZAROZ_API/projects/$PROJECT/stats" -H "$AUTH"curl -sS -X DELETE "$ZAROZ_API/projects/$PROJECT" -H "$AUTH" # 204, solo si no tiene suscripciones
TypeScript
Code
const project = await call("POST", `/organizations/${ORG}/projects`, { name: "Production", slug: "production",});await call("PATCH", `/projects/${project.body.id}`, { name: "Live" });const del = await call("DELETE", `/projects/${project.body.id}`);console.log(del.status); // 204, o 4xx mientras tenga suscripciones
En una organización personal el slug games está reservado al panel de juegos (422 project-slug-reserved) y ese proyecto no se puede cambiar aquí (403 project-gaming-managed).
Invitar a personas
Invita por correo con el rol que deben recibir. La respuesta es la misma tenga o no cuenta esa dirección, así que la API no sirve para averiguar quién está registrado.
Tu propio correo debe estar verificado para poder invitar. El envío tiene límite de frecuencia, y una dirección que rechazó tiene un periodo de espera de 30 días antes de poder ser invitada de nuevo; ambos casos responden 429 con un code legible por máquina.
La persona invitada, con sesión iniciada con el mismo correo verificado, ve la invitación y la responde:
curl
Code
curl -sS "$ZAROZ_API/me/invitations?status=pending" -H "$AUTH"curl -sS -X POST "$ZAROZ_API/invitations/$INVITATION/accept" -H "$AUTH"curl -sS -X POST "$ZAROZ_API/invitations/$INVITATION/decline" -H "$AUTH"curl -sS -X POST "$ZAROZ_API/invitations/$INVITATION/allow-reinvite" -H "$AUTH" # levantar antes la espera
Aceptar se puede repetir (una segunda aceptación no cambia nada) y también funciona sobre una invitación rechazada que no haya caducado. Si ya perteneces a esa organización la respuesta es 409 y la invitación se cancela: aceptar nunca cambia el rol de un miembro existente.
Añadir, cambiar y quitar miembros
Si ya conoces el id de cuenta de una persona puedes añadirla directamente, sin invitación.
const members = await call("GET", `/organizations/${ORG}/members`);for (const m of members.body) console.log(m.name, m.email, m.role);await call("PATCH", `/organizations/${ORG}/members/${USER}`, { role: "admin" });await call("DELETE", `/organizations/${ORG}/members/${USER}`);
Python
Code
_, members = call("GET", f"/organizations/{ORG}/members")for m in members: print(m["name"], m["email"], m["role"])call("PATCH", f"/organizations/{ORG}/members/{USER}", {"role": "admin"})call("DELETE", f"/organizations/{ORG}/members/{USER}")
Volver a añadir a un miembro existente devuelve la membresía sin cambios. Leer la lista de miembros de una organización a la que no perteneces responde 404, igual que una que no existe.
País de facturación
Una compra en una organización compartida necesita el país en el que tributa. Un presupuesto responde billing-country-required hasta que se fija. Los propietarios y administradores lo fijan una vez; repetir el mismo valor funciona y uno distinto se rechaza con billing-country-already-set.
Demostrar que la organización controla un dominio se hace con un registro DNS TXT. Inicia el desafío, publica el registro y pide una comprobación (la plataforma también vuelve a comprobar por su cuenta).
curl
Code
curl -sS -X POST "$ZAROZ_API/organizations/$ORG/domains" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"domain": "example.com"}'# {"domain":"example.com","record_type":"TXT","record_name":"...","record_value":"...","status":"...", ...}# publica el registro TXT en record_name con record_value y entonces:curl -sS -X POST "$ZAROZ_API/organizations/$ORG/domains/example.com/check" -H "$AUTH"curl -sS "$ZAROZ_API/organizations/$ORG/domains" -H "$AUTH"curl -sS -X DELETE "$ZAROZ_API/organizations/$ORG/domains/example.com" -H "$AUTH"
_, challenge = call("POST", f"/organizations/{ORG}/domains", {"domain": "example.com"})print("TXT", challenge["record_name"], "=", challenge["record_value"])# tras publicar el registro:_, checked = call("POST", f"/organizations/{ORG}/domains/example.com/check")print(checked["status"], checked["last_error"])
La comprobación hace una consulta DNS real y tiene un límite de frecuencia estricto, así que espera a que el registro se propague antes de volver a llamarla. last_error indica lo que encontró la consulta. (Esto demuestra la propiedad de un dominio para la organización; para poner un dominio delante de un servicio consulta Dominios personalizados.)
Registro de actividad
Todo lo hecho en la organización se lista, lo más reciente primero, con quién lo hizo (una persona, o un token de API por su nombre). Acótalo con project_id, service_instance_id o action.
curl
Code
curl -sS "$ZAROZ_API/organizations/$ORG/audit?page=1&page_size=50" -H "$AUTH"curl -sS "$ZAROZ_API/service-instances/$SERVICE/activity" -H "$AUTH" # solo un servicio
TypeScript
Code
const log = await call("GET", `/organizations/${ORG}/audit?page_size=20`);for (const e of log.body.data) console.log(e.created_at, e.action, e.principal_name ?? e.api_token_name);
Python
Code
_, log = call("GET", f"/organizations/{ORG}/audit?page_size=20")for e in log["data"]: print(e["created_at"], e["action"], e["principal_name"] or e["api_token_name"])
Los eventos internos de la plataforma nunca aparecen aquí: solo lo que los clientes hicieron en tu organización.
Borrar una organización
Solo un propietario puede, y solo cuando está vacía: sin proyectos (bórralos antes) y sin saldo en el monedero. Una organización personal no se puede borrar.