API para socios, versión 1

Evaluaciones dentro de su propio sitio web

Muestre nuestras pruebas de práctica en sus páginas o use pruebas propias: su servidor inicia un intento, el candidato lo hace en su página y el resultado vuelve a usted.

Dirección de la API
https://www.supergb.com/cbt/partner-api/v1

Cómo encaja todo

  1. Cree claves y añada sus sitios web en la consola.
  2. Para pruebas de práctica, pegue el fragmento en su página.
  3. Para sus propias pruebas, su servidor inicia un intento y recibe una dirección de inicio.
  4. Su página la abre, el candidato hace la prueba y el resultado le llega por webhook o desde la API.

Claves

pk_test_ pk_live_
Las claves publicables van en sus páginas web. Solo abren pruebas de práctica en los sitios que indicó.
sk_test_ sk_live_
Las claves de servidor actúan en nombre de su organización. Guárdelas en su servidor y no las envíe nunca a un navegador.

Las claves de prueba funcionan de inmediato y no se descuentan de su plan. Las claves live requieren que su cuenta esté aprobada.

Pruebas de práctica

Añada el script una vez y coloque una prueba donde quiera. El marco se ajusta solo a su contenido.

<div id="gb-test"></div>
<script src="https://www.supergb.com/cbt/js/embed/v1.js"></script>
<script>
  GreenBridge.mount("#gb-test", { key: "pk_live_...", paper: "PAPER_ID" });
</script>

La prueba es el id que muestra el generador de fragmentos de su consola. Añada mode: "exam" para condiciones de examen con tiempo.

Sus propias pruebas

Escriba pruebas en la consola, en Pruebas, y ábralas. Cuando un candidato esté listo, su servidor inicia un intento:

curl -X POST https://www.supergb.com/cbt/partner-api/v1/sessions \
  -H "Authorization: Bearer $GREEN_BRIDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"test_id": "TEST_ID", "language": "fr", "candidate": {"id": "learner-42", "name": "Ada Obi", "email": "ada@example.com"}}'

candidate.id es su propio id para la persona, hasta 128 caracteres. El nombre y el correo son opcionales; solo guardamos lo que envíe.

language es opcional: uno de de, en, es, fr, yo, ig, ha, nl, pt, sw. Los botones, el temporizador y los mensajes del intento aparecen en ese idioma; sus preguntas quedan tal como las escribió. Sin este campo, el intento es en inglés.

La respuesta incluye una dirección de inicio que funciona una vez, durante 10 minutos. Ábrala en su página:

HTTP/1.1 201 Created

{
  "attempt_id": "att_...",
  "launch_token": "lt_...",
  "launch_url": "https://www.supergb.com/cbt/fr/embed/v1/test?launch=lt_...",
  "launch_expires_at": "2026-10-23T09:10:00Z",
  "live": true,
  "language": "fr"
}
<div id="gb-test"></div>
<script src="https://www.supergb.com/cbt/js/embed/v1.js"></script>
<script>
  GreenBridge.mountTest("#gb-test", {
    launchUrl: "LAUNCH_URL_FROM_YOUR_SERVER",
    onEvent: function (event) {
      if (event.type === "submitted") {
        showThanks(event.detail.attempt_id);
      }
    }
  });
</script>

Una vez abierto, un intento dura hasta 24 horas y al recargar se reanuda. Cada candidato hace cada prueba una vez.

Para listar sus pruebas y sus ids:

curl https://www.supergb.com/cbt/partner-api/v1/tests -H "Authorization: Bearer $GREEN_BRIDGE_KEY"

Mensajes del marco

onEvent recibe estos mensajes, y solo desde nuestro marco:

EventoSignificado
readyLa página se ha cargado.
resizeEl contenido cambió de altura. El marco lo sigue solo.
completedSe corrigió una prueba de práctica. detail incluye score y max_score.
submittedSe entregó una prueba. detail incluye attempt_id. Obtenga el resultado desde su servidor, no desde el navegador.

Resultados

Intentos entregados, del más reciente al más antiguo, 50 por página. Filtre por test_id, candidate_id o ambos.

curl "https://www.supergb.com/cbt/partner-api/v1/attempts?test_id=TEST_ID&page=0" -H "Authorization: Bearer $GREEN_BRIDGE_KEY"
curl https://www.supergb.com/cbt/partner-api/v1/attempts/ATTEMPT_ID -H "Authorization: Bearer $GREEN_BRIDGE_KEY"

Un intento tiene este aspecto. questions se incluye desde el plan Growth.

{
  "id": "att_...",
  "test_id": "TEST_ID",
  "candidate_id": "learner-42",
  "live": true,
  "language": "fr",
  "started_at": "2026-10-23T09:02:11Z",
  "submitted_at": "2026-10-23T09:41:57Z",
  "integrity_events": 0,
  "score": 34.0,
  "max_score": 40.0,
  "percent": 85.0,
  "grading_status": "fully_graded",
  "questions": [
    {"question_id": "q1", "type": "multiple_choice_question", "score": 1.0, "max_score": 1.0}
  ]
}

grading_status es fully_graded cuando no queda nada por corregir a mano; si no, pending_manual_review o pending_transcription.

Webhooks

Añada hasta 5 direcciones https en su consola. Cada evento se envía como POST firmado y se reintenta durante 3 días hasta que su servidor responda con un estado 2xx.

EventoSignificado
attempt.startedEl candidato abrió el intento.
attempt.submittedEl candidato entregó.
attempt.gradedTodas las notas son definitivas. Se envía de nuevo cada vez que cambia una nota.
attempt.integrity_flaggedEl candidato salió de la prueba o intentó copiar o pegar 3 veces.
pingUn evento de prueba enviado desde su consola.
POST /hooks/green-bridge
Content-Type: application/json
Green-Bridge-Event: attempt.graded
Green-Bridge-Delivery: whd_...
Green-Bridge-Signature: t=1792834917,v1=5f0c...

{
  "id": "evt_graded_att_..._1",
  "type": "attempt.graded",
  "created_at": "2026-10-23T10:21:57Z",
  "data": { "id": "att_...", "candidate_id": "learner-42", "score": 34.0, "max_score": 40.0, "grading_status": "fully_graded" }
}

El id de un evento nunca cambia, así que puede ignorar sin riesgo uno que ya haya procesado.

Comprobar la firma

Calcule el HMAC-SHA256 de t, un punto y el cuerpo sin procesar con su secreto de firma, y compárelo con v1. Rechace una marca de tiempo de más de cinco minutos.

Node.js

const crypto = require("crypto");

function isFromGreenBridge(header, rawBody, secret) {
  const parts = Object.fromEntries(header.split(",").map(part => part.split("=")));
  if (!parts.t || !parts.v1 || Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) {
    return false;
  }
  const expected = crypto.createHmac("sha256", secret).update(parts.t + "." + rawBody).digest("hex");
  return expected.length === parts.v1.length
    && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Python

import hashlib, hmac, time

def is_from_green_bridge(header, raw_body, secret):
    parts = dict(part.split("=", 1) for part in header.split(","))
    if "t" not in parts or abs(time.time() - int(parts["t"])) > 300:
        return False
    signed = parts["t"].encode() + b"." + raw_body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))

Errores

Los errores llegan como JSON con un código estable:

HTTP/1.1 404 Not Found

{"error": {"code": "test_not_found"}}
Código HTTP Significado
invalid_key 401 Falta la clave, no se reconoce o está revocada.
partner_suspended 403 Su cuenta está suspendida. Contáctenos.
live_keys_need_approval 403 Las claves live funcionan cuando su cuenta está aprobada.
not_on_plan 403 Su plan no incluye esto.
test_not_found 404 Ninguna de sus pruebas tiene ese id.
attempt_not_found 404 Ninguno de sus intentos tiene ese id.
candidate_not_found 404 No tiene ningún candidato con ese id.
test_not_open 409 La prueba aún no está abierta o ya se cerró.
already_submitted 409 Este candidato ya entregó esta prueba.
invalid_request 400 Falta un campo o no tiene la forma esperada.
monthly_limit_reached 429 Se agotó la cuota del mes. Las claves de prueba siguen funcionando.
internal_error 500 Algo falló de nuestro lado. Inténtelo de nuevo.

Límites y datos

  • Hasta 300 solicitudes por minuto por cada clave de servidor. Por encima, la respuesta es 429 sin contenido; espere un minuto y vuelva a intentarlo.
  • Los intentos live y la corrección con IA se descuentan de la cuota mensual de su plan. Los intentos iniciados con una clave de prueba no cuentan.

Sus datos

Qué guardamos de sus pruebas y candidatos, durante cuánto tiempo y cómo recuperarlo.

Pruebas y sus preguntas
Se guardan hasta que las elimine o cierre su cuenta.
Candidatos
El id que envíe, y un nombre y un correo solo si los envía. Se guardan durante un año desde la última vez que se vio al candidato.
Intentos y resultados
Respuestas, grabaciones, notas y eventos de integridad. Se guardan durante un año desde el inicio del intento y después se borran.
Pruebas de práctica
Se guardan durante un año, solo para contar su consumo. La puntuación llega a su página en el evento completed.
Entregas de webhooks
Se guardan 30 días, en el registro de entregas de su consola.
Consumo de la API
Recuentos diarios por clave, guardados durante 400 días, en la pantalla Consumo de su consola.

Obtenga los resultados en cualquier momento con GET /attempts. Con los planes Growth e Institution también puede descargar los resultados de cada prueba en CSV desde el menú de la prueba en su consola: una fila por intento con la nota de cada pregunta y la respuesta del candidato en las preguntas que usted escribió. Las preguntas del banco de Green Bridge solo muestran sus notas.

Para borrar a un candidato antes:

curl -X POST https://www.supergb.com/cbt/partner-api/v1/candidates/erase \
  -H "Authorization: Bearer $GREEN_BRIDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"candidate_id": "learner-42"}'

Un resultado que un candidato guarda en su propia cuenta de Green Bridge le pertenece desde ese momento. Borrar al candidato o cerrar su cuenta no lo elimina.

El propietario de su cuenta puede cerrarla en Sitios web y claves. Las claves y los webhooks se detienen de inmediato y todo lo anterior se borra en un día, así que descargue antes lo que necesite.

Los compromisos que respaldan esto figuran en Socios y tratamiento de datos de nuestros Términos y Condiciones.

¿Necesita algo que los planes no cubren? Use Contáctenos en la pantalla Plan de su consola.