GreenStack API v2 — Especificación Técnica

Versión 2.1.0 · Actualizado 2026-06-12 · Acceso solo para integradores certificados.

Esta especificación describe todos los endpoints REST de la plataforma GreenStack para la gestión de huella de carbono empresarial. La API sigue los principios REST; los recursos devuelven JSON y las respuestas de error siguen RFC 9457.


Autenticación

OAuth 2.0 — Client Credentials

La API usa el flujo Client Credentials de OAuth 2.0. Obtén un token de acceso con:

POST https://auth.greenstack.io/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&scope=emissions:read emissions:write reports:read

Respuesta:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "emissions:read emissions:write reports:read"
}

Incluye el token en cada petición:

Authorization: Bearer {access_token}

Scopes disponibles

ScopeDescripción
emissions:readLeer registros de emisiones
emissions:writeCrear y editar registros
reports:readDescargar informes PDF/CSV
reports:generateLanzar generación de informes asíncronos
admin:orgsGestionar organizaciones (solo partners)

Recursos

Organizaciones

Una organización representa a la empresa cliente. Todas las peticiones van namespaced por org_id.

GET /v2/orgs/{org_id}

Devuelve los metadatos de una organización.

GET /v2/orgs/org_01HXYZ1234 HTTP/1.1
Host: api.greenstack.io
Authorization: Bearer {token}

Respuesta 200 OK:

{
  "id": "org_01HXYZ1234",
  "name": "Café Raíz SL",
  "country": "ES",
  "sector": "food_beverage",
  "reporting_year": 2025,
  "baseline_year": 2022,
  "created_at": "2024-03-15T09:22:00Z",
  "status": "active"
}

PATCH /v2/orgs/{org_id}

Actualiza campos de la organización. Solo name, country y reporting_year son mutables.

{
  "reporting_year": 2025
}

Emisiones

Los registros de emisiones representan actividades con impacto de carbono. Cada registro pertenece a un scope (1, 2 o 3) y a una categoría GHG Protocol.

Modelo de datos

CampoTipoObligatorioDescripción
idstringULID generado por servidor
org_idstringID de la organización
scope`1\2\3`Alcance GHG Protocol
categorystringCódigo de categoría (ej. stationary_combustion)
activity_valuenumberCantidad de la actividad (kWh, km, t…)
activity_unitstringUnidad de medida (ISO 80000)
emission_factor_idstringID del factor de emisión usado
co2e_kgnumberCalculado automáticamente por el servidor
datestringISO 8601 (YYYY-MM-DD)
notesstringnoTexto libre, máx. 500 chars
tagsstring[]noEtiquetas para filtrado
source_docstringnoURL del documento fuente

GET /v2/orgs/{org_id}/emissions

Lista registros con paginación tipo cursor.

Parámetros de query:

ParámetroTipoDefaultDescripción
scope`1\2\3`todosFiltrar por alcance GHG
categorystringtodosFiltrar por categoría
date_fromdateDesde fecha (YYYY-MM-DD)
date_todateHasta fecha (YYYY-MM-DD)
tagstringFiltrar por etiqueta
cursorstringCursor para siguiente página
limitinteger50Máx. 200

Respuesta 200 OK:

{
  "data": [
    {
      "id": "01HXAB1234",
      "scope": 1,
      "category": "stationary_combustion",
      "activity_value": 1200.5,
      "activity_unit": "kWh",
      "co2e_kg": 264.11,
      "date": "2025-10-01",
      "tags": ["planta-madrid", "produccion"]
    }
  ],
  "cursor_next": "eyJpZCI6IjAxSFhBQjEyMzQifQ",
  "total_count": 847,
  "has_more": true
}

POST /v2/orgs/{org_id}/emissions

Crea un nuevo registro.

{
  "scope": 2,
  "category": "purchased_electricity",
  "activity_value": 8540.0,
  "activity_unit": "kWh",
  "emission_factor_id": "ef_es_grid_2025",
  "date": "2025-11-30",
  "notes": "Factura nov 2025, contrato Endesa verde",
  "tags": ["oficina-bcn"]
}

Respuesta 201 Created:

{
  "id": "01HXBC5678",
  "co2e_kg": 1282.6,
  "co2e_kg_details": {
    "factor_value": 0.15,
    "factor_unit": "kgCO2e/kWh",
    "factor_version": "MiTECO-2025"
  }
}

DELETE /v2/orgs/{org_id}/emissions/{emission_id}

Elimina un registro. Operación irreversible. Requiere scope emissions:write.

Respuesta: 204 No Content.


Factores de emisión

Base de datos de referencia con más de 12.000 factores certificados (DEFRA, MiTECO, IPCC AR6).

GET /v2/emission-factors

GET /v2/emission-factors?country=ES&category=purchased_electricity&year=2025

Respuesta 200 OK:

{
  "data": [
    {
      "id": "ef_es_grid_2025",
      "name": "Red eléctrica española 2025",
      "country": "ES",
      "category": "purchased_electricity",
      "value": 0.15,
      "unit": "kgCO2e/kWh",
      "source": "MiTECO",
      "year": 2025,
      "status": "active"
    }
  ]
}

Informes

Los informes se generan de forma asíncrona. El flujo es: lanzar → polling de estado → descargar.

POST /v2/orgs/{org_id}/reports

Lanza la generación de un informe.

{
  "type": "annual_ghg",
  "year": 2025,
  "format": "pdf",
  "standard": "GHG_Protocol",
  "locale": "es"
}

Tipos de informe disponibles:

Respuesta 202 Accepted:

{
  "report_id": "rpt_01HXDE1234",
  "status": "queued",
  "estimated_seconds": 45
}

GET /v2/orgs/{org_id}/reports/{report_id}

Polling de estado.

EstadoDescripción
queuedEn cola de generación
processingGenerando el documento
readyListo para descarga
failedError en generación (ver error)

GET /v2/orgs/{org_id}/reports/{report_id}/download

Descarga el archivo. Redirige (302) al URL firmado de S3 (válido 15 minutos).


Manejo de errores

La API sigue RFC 9457 (Problem Details for HTTP APIs):

{
  "type": "https://errors.greenstack.io/validation-error",
  "title": "Validation Error",
  "status": 422,
  "detail": "activity_value must be a positive number",
  "instance": "/v2/orgs/org_01HXYZ1234/emissions",
  "errors": [
    { "field": "activity_value", "code": "must_be_positive", "value": -10 }
  ]
}

Códigos de estado habituales

CódigoSignificado
200OK — petición exitosa
201Creado — recurso nuevo
202Aceptado — trabajo asíncrono iniciado
204Sin contenido — operación exitosa sin cuerpo
400Petición malformada
401No autenticado — token inválido o expirado
403Prohibido — scope insuficiente
404No encontrado
422Error de validación — ver errors[]
429Rate limit — ver cabecera Retry-After
500Error interno del servidor

Rate Limiting

Los límites se aplican por client_id:

PlanPeticiones/minutoPeticiones/día
Starter605.000
Business30050.000
Enterprise1.000sin límite

Las cabeceras X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset están presentes en cada respuesta.


Webhooks

Suscríbete a eventos asíncronos para evitar polling activo.

Eventos disponibles

Firma de seguridad

Cada entrega incluye la cabecera X-GreenStack-Signature:

import hmac, hashlib

def verify_webhook(payload_bytes: bytes, signature_header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), payload_bytes, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

SDKs y ejemplos

Librerías oficiales mantenidas por el equipo GreenStack:

LenguajeRepositorioVersión
Pythongreenstack-io/sdk-python2.1.0
TypeScript / Nodegreenstack-io/sdk-ts2.1.0
Gogreenstack-io/sdk-go2.0.3
Javagreenstack-io/sdk-java2.0.1

Ejemplo completo Python

from greenstack import GreenStackClient

client = GreenStackClient(
    client_id="YOUR_CLIENT_ID",
    client_secret="YOUR_CLIENT_SECRET",
)

# Crear registro de emisiones
record = client.emissions.create(
    org_id="org_01HXYZ1234",
    scope=2,
    category="purchased_electricity",
    activity_value=8540.0,
    activity_unit="kWh",
    emission_factor_id="ef_es_grid_2025",
    date="2025-11-30",
)
print(f"Registro {record.id}: {record.co2e_kg:.2f} kgCO2e")

# Generar informe anual
report = client.reports.generate(
    org_id="org_01HXYZ1234",
    type="annual_ghg",
    year=2025,
    format="pdf",
)
report.wait()  # bloquea hasta status=ready
report.download(path="./informe_ghg_2025.pdf")
print("Informe descargado.")

Changelog

v2.1.0 (2026-06-12)

v2.0.0 (2025-09-01)

v1.9 (deprecada)


Documentación generada por CULTIVA IA para GreenStack SaaS. Para soporte de integración: developers@greenstack.io