REST · OpenAPI 3.1 · HMAC webhooks · Incremental SQL patches

Integrá datos regulatorios cosméticos UE en tu producto

Dejá de scrappear ec.europa.eu y dejá de mantener tu propio diff engine. BD-API entrega la base CosIng UE como patches SQL firmados incrementales, y eventos regulatorios multi-fuente (EC Publications, SCCS, Safety Gate, EUR-Lex) como webhooks firmados HMAC. Sin SDK lock-in, sin runtime propietario.

# Check current CosIng version
curl -X POST https://bdapi.bighubai.com/api/versions/check \
  -H "Authorization: Bearer $LICENSE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"current_version": "1.0.0"}'

# If newer version available, download the incremental patch
curl https://bdapi.bighubai.com/api/versions/1.1.0/patch \
  -H "Authorization: Bearer $LICENSE_KEY" \
  -o patch.sql

# Verify SHA-256 integrity (hash ships in response headers)
curl -sI https://bdapi.bighubai.com/api/versions/1.1.0/patch \
  -H "Authorization: Bearer $LICENSE_KEY" \
  | grep -i x-hash-sha256

# Apply inside a single PostgreSQL transaction, then confirm
psql -1 -f patch.sql && curl -X POST .../api/versions/confirm \
  -H "Authorization: Bearer $LICENSE_KEY" \
  -d '{"version":"1.1.0","success":true,"error":null}'

Pack completo bajo solicitud: OpenAPI 3.1 spec, code samples en curl/Node/Python/Go/PHP, contrato de webhooks para los dos canales, runbooks de operación.

Qué entrega BD-API

Cuatro artefactos. Sin SDK lock-in.

BD-API entrega cuatro deliverables bien definidos. Todo es HTTP, JSON o SQL — sin cliente propietario ni protocolo binario opaco. Cualquier cosa que hable REST y PostgreSQL puede integrarse.

01CosIng como patches SQL

Incremental, firmado, aplicado en una transacción

Cada release de CosIng se entrega como un patch.sql idempotente más changelog.json y meta.json. Hash de integridad SHA-256 en headers de respuesta (X-Hash-SHA256); aplicá el patch dentro de una transacción PostgreSQL y hacé rollback si el hash no coincide.

Estructura del bundle del patch

bdapi-patch-1.2.0.zip
├── patch.sql           # idempotent SQL, runs in a single PostgreSQL transaction
├── changelog.json      # human + machine-readable diff summary
└── meta.json           # version, generated_at, sha256, row counts
02Eventos regulatorios como webhooks

HMAC-SHA256, dos canales paralelos, granular por fuente

EC Publications (Diario Oficial UE) se entrega como webhooks firmados HMAC con headers X-BDAPI-*. Opiniones SCCS, alertas Safety Gate y actos EUR-Lex se entregan por un segundo canal con headers X-BDAPI-Watch-*. Mismo algoritmo, headers distintos. Tres reintentos con backoff exponencial 1s / 2s / 4s, idempotency keys en cada evento. Suscripción por fuente.

Request webhook entrante — ambos canales

POST https://your-app.example/webhooks/bdapi
# Channel 1 — EC Publications:
#   X-BDAPI-Event: ec.publication.detected
#   X-BDAPI-Timestamp: 1748016600  (unix seconds)
#   X-BDAPI-Signature: sha256=9f2c…b71d

# Channel 2 — Regulatory Watch (SCCS / Safety Gate / EUR-Lex):
#   X-BDAPI-Watch-Event: watch.safety_gate.alert.detected
#   X-BDAPI-Watch-Timestamp: 1748016600  (unix seconds)
#   X-BDAPI-Watch-Signature: sha256=9f2c…b71d
#   X-BDAPI-Watch-Delivery: 01HQZK9YBV…  (UUID per delivery)

{ "event": "watch.safety_gate.alert.detected", "tier": "premium", … }
03REST API

Versionada, JSON, spec OpenAPI 3.1

La superficie completa está descrita por un documento OpenAPI 3.1 en YAML entregado como parte del pack de integración. Generá un cliente tipado con openapi-generator, oapi-codegen, openapi-typescript o cualquier otra herramienta que consuma OpenAPI — o quedate con HTTP crudo. Ambos paths son first-class.

Extracto de la spec OpenAPI

openapi: 3.1.0
info:
  title: BD-API — Contrato público para integradores
  version: 1.0.0

# Shipped as part of the integration pack on request — drop into:
#   openapi-generator generate -i 15-OPENAPI.yaml -g typescript-axios
#   oapi-codegen --package bdapi 15-OPENAPI.yaml > bdapi.gen.go
#   prism mock 15-OPENAPI.yaml   # mock server for integration tests
04Auth con license key

Bearer token por instalación, rotación bajo solicitud

Una license key por instalación, enviada como Authorization: Bearer $LICENSE_KEY. Las keys están scopeadas a la instalación — las queries filtran por client_id automáticamente. La rotación se solicita por soporte; la política planeada es una ventana de solapamiento de 24 horas (Próximamente Q3 2026) para que rolés deploys sin un cutover duro.

Request autenticado

curl https://bdapi.bighubai.com/api/versions/check \
  -H "Authorization: Bearer $LICENSE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"current_version":"1.0.0"}'

# Key rotation: requested via support — old + new accepted
# for a 24h overlap window (Coming Q3 2026).

Ejemplo de changelog.json

{
  "from_version": "1.1.4",
  "to_version": "1.2.0",
  "generated_at": "2026-05-15T08:30:00Z",
  "sha256": "9f2c…b71d",
  "changes": {
    "added":    [{ "inci_name": "…", "annex": "VI", "cas": "…" }],
    "modified": [{ "inci_name": "…", "field": "restriction" }],
    "removed":  []
  }
}

Arquitectura de integración

Dónde encaja BD-API en tu stack

BD-API es un único componente upstream entre las fuentes oficiales UE y tu aplicación. Dos canales: una REST API que consultás cuando vos quieras y webhooks salientes firmados HMAC para eventos sensibles al tiempo. Nada más toca tu base de datos.

┌─────────────────────┐                          ┌──────────────────────┐
│  EU sources         │                          │   Your product       │
│  CosIng · SCCS      │                          │   (cosmetic SW)      │
│  Safety Gate        │      pull  (REST)        │                      │
│  EUR-Lex            │ ◄─────────────────────── │   • PostgreSQL       │
└──────────┬──────────┘                          │   • Webhook endpoint │
           │                                     │   • Your domain UI   │
           │ poll (CRON, advisory-locked)        │                      │
           ▼                                     │                      │
┌─────────────────────┐      push (HMAC)         │                      │
│      BD-API         │ ───────────────────────► │                      │
│   (this service)    │                          │                      │
└─────────────────────┘                          └──────────────────────┘

Topología de integración — pull del lado REST, push del lado webhook.

Pull

GET /api/versions/check

Tu aplicación consulta /api/versions/check con la frecuencia que quiera (recomendado: diaria). La respuesta es la versión CosIng actual más el SHA-256 del patch que te lleva desde tu last_applied_version hasta la actual. No se descarga nada hasta que lo pidas.

Push

POST a tu webhook URL

BD-API envía webhooks firmados HMAC-SHA256 cuando se detecta un evento regulatorio. Dos canales comparten infraestructura: EC Publications usa headers X-BDAPI-*; Regulatory Watch (SCCS / Safety Gate / EUR-Lex) usa headers X-BDAPI-Watch-*. Tres reintentos, backoff exponencial 1s / 2s / 4s. Cada dispatch Watch trae X-BDAPI-Watch-Delivery (UUID) para procesamiento idempotente de tu lado.

Apply

BEGIN; \i patch.sql; COMMIT;

Los patches son SQL idempotente diseñado para correr dentro de una sola transacción PostgreSQL. Aplicalo primero en una réplica si querés — el changelog.json declara el impacto a nivel de fila por adelantado para que planees downtime si hace falta (la mayoría no son bloqueantes).

Verify

SHA-256 + HMAC en cada paso

Cada patch trae un SHA-256 en el header X-Hash-SHA256; cada webhook trae una firma HMAC-SHA256 sobre `timestamp + "." + body`. Mismatch en cualquiera de los dos significa rollback (patch) o retorno 4xx (webhook). Las fallas son observables desde tu lado sin tener que escribir a soporte.

Autenticación y rate limits

Cómo está asegurado el canal

La autenticación es un único Bearer token por instalación. No hay handshake OAuth, ni firma por request, ni certificado del lado cliente. La simplicidad operativa es intencional — un dev no debería necesitar una guía de integración de 30 páginas para hacer su primer call autenticado.

01License key

Bearer token en el header Authorization

Cada instalación recibe una license key (UUID v4). Envialá como Bearer token estándar en cada request. Las keys se revocan a pedido — flippear bdapi_clients.is_active = false la invalida inmediatamente.

Header del request

Authorization: Bearer $LICENSE_KEY
02Rate limits

Sin throttle hostil hoy; abuso dispara revisión manual

/api/versions/* está diseñado para polling diario por instalación. No hay rate limit enforced en la superficie autenticada hoy — polling de hasta una vez por minuto está bien para integration testing. El endpoint público /api/leads (usado por esta landing) tiene rate limit por IP y por email. Rate limits adaptativos por license key están en el roadmap (ver código).

Política de rate limit (roadmap Q3 2026)

# /api/versions/* — designed for daily polling per installation.
# No throttle enforced today; up to once per minute is fine for testing.
# Heavy abusive patterns may trigger manual review by BigHubAI ops.

# Public /api/leads (used by this landing page) is rate-limited per IP
# and per email — returns HTTP 429 with Retry-After when exceeded.

# Roadmap (Coming Q3 2026): per-license-key adaptive rate limit
# with response headers X-RateLimit-Remaining and X-RateLimit-Reset.
03Rotación

Rotación por soporte — solapamiento de 24h en el roadmap

Hoy, la rotación de license key se solicita por el canal de soporte. La política planeada es rotación self-service con una ventana de solapamiento de 24 horas donde la key vieja y la nueva autentican — para que rolés deployments sin coordinar un cutover duro. ETA Q3 2026.

Flujo de rotación (roadmap Q3 2026)

# 1. Request a new key via support (replaces the admin UI flow,
#    which is internal to BigHubAI ops).
# 2. Roll your deployment with the new $LICENSE_KEY.
# 3. Old key remains active during the overlap window.

# Roadmap (Coming Q3 2026): self-service rotation with a 24h
# overlap window where both old and new keys authenticate.
04Scope

Las license keys están scopeadas por instalación

Una license key autentica exactamente una instalación; cada query filtra por client_id derivado del bearer token. Para integraciones multi-tenant, pedí una key por tenant si necesitás aislamiento, o una key con atribución de tenant manejada dentro de tu aplicación. Respuestas explícitas 403 forbidden_scope para intentos cross-installation están en el roadmap.

Enforcement del scope

GET /api/versions/check
Authorization: Bearer $LICENSE_KEY_TENANT_A

# Returns version state for installation A only — every query
# filters by client_id derived from the bearer token automatically.

# Roadmap (Coming Q3 2026): explicit 403 forbidden_scope response
# when a request tries to reach data outside its installation.

Payload del webhook

Qué llega a tu endpoint

Cada evento es un POST JSON con headers de atestación. Dos canales comparten infraestructura pero usan familias de headers distintas: EC Publications usa headers X-BDAPI-*; el subsistema Regulatory Watch (SCCS, Safety Gate, EUR-Lex — mostrado abajo) usa headers X-BDAPI-Watch-*. El body es el documento canónico del evento, incluyendo análisis enriquecido con IA cuando esté disponible. Las fallas de tu lado (5xx, timeout) disparan la política de reintentos automáticamente.

Payload de ejemplo — alerta Safety Gate (canal Watch)

{
  "event": "watch.safety_gate.alert.analyzed",
  "event_id": "01HQZK9YBV-7M8K-3R2N-0P4S-5T6U7V8W9X0Y",
  "source_engine": "safety_gate",
  "source_id": 12345,
  "tier": "premium",
  "timestamp": "2026-05-15T08:32:11.000Z",
  "item": {
    "alert_number": "A12/01234/26",
    "report_id": "12345",
    "product_name": "Cosmetic moisturiser, brand X",
    "brand": "Brand X",
    "risk_type": "Chemical",
    "risk_level": "serious",
    "notifying_country": "DE",
    "country_of_origin": "CN",
    "source_url": "https://ec.europa.eu/safety-gate-alerts/screen/webReport/alertDetail/12345",
    "published_at": "2026-05-15T00:00:00Z",
    "detected_at": "2026-05-15T08:00:00Z"
  },
  "analysis": {
    "criticality": "CRITICAL",
    "summary_es": "Notificación A12/01234/26: producto leave-on excede el límite Annex V de MIT (0.0015 %). Estado miembro notificante: Alemania. Sin período de transición — retirada recomendada para SKUs afectados.",
    "risk_assessment": "Concentración de MIT detectada por encima del límite regulatorio en formulación de aplicación prolongada.",
    "regulatory_implications": "Annex V entry 57 — MIT prohibido en leave-on desde el Reglamento (UE) 2017/1224.",
    "cross_market_relevance": "Relevante para los 27 EM. Producto en e-commerce paneuropeo.",
    "recommended_action_for_brand_owners": "Auditar fórmulas, retirar lotes afectados, notificar PCPC nacional.",
    "needs_human_review": false,
    "confidence": 0.92,
    "model": "claude-sonnet-4-5"
  }
}

Request HTTP completo (headers + extracto del body)

POST /webhooks/bdapi HTTP/1.1
Host: your-app.example
Content-Type: application/json
X-BDAPI-Watch-Event:     watch.safety_gate.alert.analyzed
X-BDAPI-Watch-Timestamp: 1747297931
X-BDAPI-Watch-Signature: sha256=9f2c4d1e8a7b3f6c2e8d1a5b4c7e9f0a2b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f
X-BDAPI-Watch-Delivery:  01HQZK9YBV-7M8K-3R2N-0P4S-5T6U7V8W9X0Y
User-Agent:              BDAPI-Watch/1.0 (+https://bdapi.bighubai.com)

{ "event": "watch.safety_gate.alert.analyzed", "source_engine": "safety_gate", ... }

Headers de atestación — canal Watch

X-BDAPI-Watch-Event
Nombre completo del evento. Formato: `watch.{engine}.{noun}.{type}` — ej. `watch.safety_gate.alert.analyzed`. El receiver debe ignorar tipos desconocidos y devolver 200.
X-BDAPI-Watch-Timestamp
Unix epoch en SEGUNDOS (no milisegundos, no ISO 8601). Usado para construir la firma. Rechazá requests más viejos que 5 minutos para defenderte de replay.
X-BDAPI-Watch-Signature
Digest hex HMAC-SHA256 de `timestamp + "." + body_crudo`, firmado con tu webhook secret. Formato: `sha256=<hex>`. ATENCIÓN: el string firmado es la concatenación, no el body solo.
X-BDAPI-Watch-Delivery
UUID v4 único por intento de delivery. Usalo como unique constraint en tu tabla inbound para que los reintentos sean no-ops. Replicado en `payload.event_id`.

Footgun

Nota: BD-API firma `timestamp + "." + body_crudo`, NO el body solo. Y firma los bytes crudos del body — si tu framework parsea JSON antes de exponer el body, capturá el payload crudo antes de parsear. Re-serializar y después hashear no va a matchear la firma. Para el canal EC Publications, cambiá los headers a X-BDAPI-Event / X-BDAPI-Timestamp / X-BDAPI-Signature — mismo algoritmo, sin X-BDAPI-Delivery.

Verificación de firma

Verificá el HMAC antes de confiar en el payload

Cuatro implementaciones de referencia — Node, Python, Go, PHP. Cada una hace lo mismo: detecta qué canal mandó el request (EC Publications o Watch), aplica una ventana de replay de 300 segundos, recalcula HMAC-SHA256 sobre `timestamp + "." + body_crudo` con tu shared secret y compara en tiempo constante. Copialas en tu handler de webhooks.

verify.mjsNode.js
import crypto from 'node:crypto'

// Express: capture the raw body BEFORE JSON parsing.
// app.use(express.json({ verify: (req, _res, buf) => { req.rawBody = buf } }))

export function verifyBdApiSignature(req, secret) {
  // Detect channel: Watch uses X-BDAPI-Watch-*, EC Publications uses X-BDAPI-*.
  const isWatch = !!req.header('X-BDAPI-Watch-Signature')
  const prefix  = isWatch ? 'X-BDAPI-Watch-' : 'X-BDAPI-'

  const ts        = req.header(prefix + 'Timestamp') || ''
  const sigHeader = req.header(prefix + 'Signature') || ''

  // Replay protection — same window for both channels (300s).
  if (Math.abs(Math.floor(Date.now() / 1000) - parseInt(ts, 10)) > 300) {
    return false
  }

  const received = sigHeader.replace(/^sha256=/, '')

  // CRITICAL: the signed message is `timestamp + "." + body`, NOT the body alone.
  const message  = ts + '.' + req.rawBody.toString('utf8')
  const expected = crypto.createHmac('sha256', secret).update(message).digest('hex')

  const a = Buffer.from(received, 'hex')
  const b = Buffer.from(expected, 'hex')
  if (a.length !== b.length) return false

  // Constant-time compare — NEVER use a === b for signatures.
  return crypto.timingSafeEqual(a, b)
}

Footgun

Nunca compares firmas con `==` ni `bytes.Equal`. Usá crypto.timingSafeEqual (Node), hmac.compare_digest (Python), hmac.Equal (Go) o hash_equals (PHP). La igualdad de strings/bytes cortocircuita en el primer byte distinto, lo que filtra la posición del byte diferente por timing — suficiente para que un atacante decidido forje una firma. Y nunca firmes el body solo — el mensaje es timestamp concatenado con el body via un punto literal.

License key de test y prácticas de sandbox

Testeá contra el comportamiento real de producción, no contra un mock stubeado

No corremos una instalación de sandbox separada. En su lugar, emitimos una license key de test dedicada que apunta al mismo entorno productivo con efectos colaterales atenuados — mismos code paths, misma lógica de firma, misma política de reintentos. Lo que ejercés en test es exactamente lo que corre en prod.

  1. 01
    License key de testPróximamente Q3 2026

    Mismo entorno, efectos colaterales atenuados

    Provisionada manualmente bajo solicitud. Autentica idéntico a las keys de producción pero el flag de modo test (Próximamente Q3 2026) manda X-BDAPI-Mode: test en webhooks salientes y saltea contadores comerciales en feedback. El audit trail se preserva. Sin rate limits artificiales durante la integración.

  2. 02
    Receiver local vía tunnel

    ngrok / Cloudflare Tunnel para testing local de webhook

    Exponé tu localhost por HTTPS con ngrok, Cloudflare Tunnel o localtunnel. Pasale la URL temporal a BigHubAI para registrarla contra tu license key de test; los dispatches reales llegan a tu laptop. Es el mejor path para el primer ciclo de desarrollo.

  3. 03
    Testing offline replicable

    Capturar, re-firmar, replay contra dev

    Capturá un payload de dispatch real desde tu staging receiver, regenerá el HMAC con tu secret de dev usando el script replay-firma.sh del pack, y POSTealo contra tu dev local. Te deja iterar sobre el parsing y la idempotencia sin esperar a un evento upstream real.

  4. 04
    OnboardingPróximamente Q3 2026

    Provisioning manual, sin ventana de trial fija

    Las keys de test se emiten durante la discusión comercial — no hay un reloj fijo de 30 días. Las keys de producción se emiten aparte una vez que la integración está firmada. Las keys de producción y de test nunca comparten estado a nivel de data — son filas distintas en bdapi_clients con flags is_active y (planeado) is_test distintos.

Para desarrolladores

Preguntas técnicas comunes

¿Hay una spec OpenAPI?+

Sí. Entregamos una spec OpenAPI 3.1 que cubre todos los endpoints públicos más los payloads de webhooks. Se entrega como parte del pack completo de integración después de que revisamos el request — importala a Postman, Insomnia, openapi-generator, oapi-codegen o cualquier herramienta que consuma OpenAPI. El pack completo se entrega solo a integradores cualificados; pedí acceso por el formulario de contacto.

¿Necesito un SDK o puedo usar HTTP crudo?+

HTTP crudo está soportado completo y es el path recomendado. Sin SDK lock-in. El pack trae code samples ejecutables en curl, Node.js, Python, Go (verificación de firma) y PHP — copialos en tu proyecto y deployás. Cualquier cliente HTTP (axios, fetch, requests, httpx, Guzzle, Go net/http) funciona.

¿Cómo recibo webhooks durante desarrollo local?+

Usá ngrok, Cloudflare Tunnel o localtunnel para exponer tu localhost por HTTPS. Para testing offline repetible, el pack incluye un script `replay-firma.sh` que re-firma un payload capturado con tu secret de dev, así iterás sin esperar un dispatch real.

¿Qué pasa si mi endpoint webhook está caído por horas?+

BD-API reintenta con backoff exponencial (1s / 2s / 4s, 3 intentos) por dispatch. Después del fallo completo, la fila del dispatch queda en el pool de fallidos y el próximo tick del CRON la reevalúa mientras `retry_count < 3`. Después del fallo permanente, el evento queda queryable via REST API para que hagas backfill manual. Los receivers deben ser idempotentes — el mismo `event_id` puede llegar más de una vez.

¿Cómo se scopea la license key?+

Cada license key autentica exactamente una instalación. Queries cross-installation no son direccionables. Para integraciones multi-tenant, pedí una key por tenant si necesitás aislamiento del lado BD-API, o una key con atribución de tenant manejada dentro de tu aplicación.

¿Y los rate limits en los endpoints /api/versions/*?+

Diseñados para polling diario por instalación. No hay rate limit hostil en esta superficie hoy — polling de mayor frecuencia está soportado (hasta una vez por minuto está bien para integration testing) pero patrones de producción deberían quedar cerca del diario, porque la fuente CosIng upstream no se actualiza más rápido.

¿Cuántas fuentes regulatorias cubre BD-API?+

Cinco fuentes activas, dos canales de integración. CosIng se entrega como patches SQL firmados incrementales via REST pull. EC Publications (Diario Oficial UE via EC Drupal), opiniones SCCS, alertas Safety Gate y actos EUR-Lex se entregan como webhooks firmados HMAC. Te suscribís por fuente — no hace falta tomar todas para tomar una. Cómo encaja cada fuente en el playbook de monitorización regulatoria →

¿Cuánto tarda una integración típica?+

Una integración funcional contra una license key de test — receiver de webhook verificando HMAC, cron diario de patches CosIng aplicando dentro de una sola transacción PostgreSQL, feedback loop cerrado — son 4 a 12 horas de ingeniería con el pack que entregamos. El hardening de producción (alerting, audit logging, atribución multi-tenant) va encima y depende de tu stack.

¿Hay sandbox o licencia de test?+

Sí. Las license keys de test se provisionan manualmente a pedido. Las keys de producción y de test apuntan al mismo entorno productivo pero el flag de modo test atenúa los efectos colaterales (sin impacto en métricas comerciales, audit trail separado). No corremos una instalación sandbox aparte — eso te da una señal más honesta: todo lo que testees se comporta igual en prod.

¿Qué pasa si BD-API deja de operar?+

La data CosIng que ya aplicaste vive en tu propio PostgreSQL — te queda. Los patches son SQL puro sin runtime propietario. Los eventos de webhook que recibiste están en tu base. No hay runtime vendor-managed que se apague, no hay SDK que deje de funcionar, no hay protocolo binario opaco que te haga lock-in. Durabilidad por diseño, no por promesa.

¿Por qué firmar webhooks con HMAC si ya uso HTTPS?+

HTTPS protege el transporte — impide que alguien en la red lea o manipule el payload en tránsito. HMAC protege el origen — permite a tu receptor probar que el payload vino realmente de BD-API y no de alguien que descubrió la URL del endpoint. Sin HMAC, cualquier atacante que adivine o descubra tu URL puede fabricar eventos. HTTPS sin HMAC es cifrado sin autenticación, y la autenticación es lo que importa para evidencia de cumplimiento. Guía de verificación HMAC de 5 minutos con ejemplos de código →

¿Qué es un timing attack y por qué importa al verificar firmas HMAC?+

Un timing attack explota el hecho de que una comparación de cadenas ingenua (== o ===) devuelve resultado en cuanto encuentra un carácter que no coincide. Un atacante que pueda medir tiempos de respuesta puede deducir bytes de la firma uno a uno hasta forjar una válida. La solución es comparación en tiempo constante — crypto.timingSafeEqual en Node, hmac.compare_digest en Python, hash_equals en PHP. El coste es idéntico al de una comparación normal; la ganancia de seguridad es total. Errores comunes de verificación HMAC — incluida la comparación temporal →

Solicitar acceso