API para parceiros, versão 1

Avaliações dentro do seu próprio site

Mostre as nossas provas de treino nas suas páginas ou use testes seus: o seu servidor inicia uma tentativa, o candidato faz-a na sua página e o resultado volta para si.

Endereço da API
https://www.supergb.com/cbt/partner-api/v1

Como tudo se encaixa

  1. Crie chaves e adicione os seus sites na consola.
  2. Para provas de treino, cole o excerto na sua página.
  3. Para os seus testes, o seu servidor inicia uma tentativa e recebe um endereço de início.
  4. A sua página abre-o, o candidato faz o teste e o resultado chega-lhe por webhook ou pela API.

Chaves

pk_test_ pk_live_
As chaves publicáveis vão nas suas páginas web. Só abrem provas de treino nos sites que indicou.
sk_test_ sk_live_
As chaves de servidor agem em nome da sua organização. Guarde-as no seu servidor e nunca as envie para um navegador.

As chaves de teste funcionam de imediato e não contam para o seu plano. As chaves live exigem que a sua conta esteja aprovada.

Provas de treino

Adicione o script uma vez e coloque uma prova onde quiser. A moldura ajusta-se sozinha ao conteúdo.

<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>

A prova é o id mostrado no gerador de excertos da sua consola. Acrescente mode: "exam" para condições de exame com tempo.

Os seus testes

Escreva testes na consola, em Testes, e abra-os. Quando um candidato estiver pronto, o seu servidor inicia uma tentativa:

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 é o seu próprio id para a pessoa, até 128 caracteres. O nome e o email são opcionais; só guardamos o que enviar.

language é opcional: um de de, en, es, fr, yo, ig, ha, nl, pt, sw. Os botões, o temporizador e as mensagens da tentativa aparecem nessa língua; as suas perguntas ficam como as escreveu. Sem este campo, a tentativa é em inglês.

A resposta traz um endereço de início que funciona uma vez, dentro de 10 minutos. Abra-o na sua 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>

Depois de aberta, uma tentativa dura até 24 horas e recarregar retoma-a. Cada candidato faz cada teste uma vez.

Para listar os seus testes e os respetivos ids:

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

Mensagens da moldura

onEvent recebe estas mensagens, e só da nossa moldura:

EventoSignificado
readyA página carregou.
resizeO conteúdo mudou de altura. A moldura acompanha sozinha.
completedUma prova de treino foi corrigida. detail traz score e max_score.
submittedUm teste foi entregue. detail traz attempt_id. Obtenha o resultado a partir do seu servidor, não do navegador.

Resultados

Tentativas entregues, da mais recente para a mais antiga, 50 por página. Filtre por test_id, candidate_id ou 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"

Uma tentativa tem este aspeto. questions está incluído a partir do plano 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 é fully_graded quando já não há nada para corrigir à mão; caso contrário, pending_manual_review ou pending_transcription.

Webhooks

Adicione até 5 endereços https na sua consola. Cada evento é enviado como POST assinado e repetido durante 3 dias até o seu servidor responder com um estado 2xx.

EventoSignificado
attempt.startedO candidato abriu a tentativa.
attempt.submittedO candidato entregou.
attempt.gradedTodas as classificações são finais. Volta a ser enviado sempre que uma nota muda.
attempt.integrity_flaggedO candidato saiu do teste ou tentou copiar ou colar 3 vezes.
pingUm evento de teste enviado da sua 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" }
}

O id de um evento nunca muda, por isso pode ignorar com segurança um que já tratou.

Verificar a assinatura

Calcule o HMAC-SHA256 de t, um ponto e o corpo original com o seu segredo de assinatura e compare com v1. Recuse uma marca temporal com mais 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", ""))

Erros

Os erros chegam em JSON com um código estável:

HTTP/1.1 404 Not Found

{"error": {"code": "test_not_found"}}
Código HTTP Significado
invalid_key 401 A chave falta, é desconhecida ou foi revogada.
partner_suspended 403 A sua conta está suspensa. Contacte-nos.
live_keys_need_approval 403 As chaves live funcionam depois de a conta ser aprovada.
not_on_plan 403 O seu plano não inclui isto.
test_not_found 404 Nenhum dos seus testes tem esse id.
attempt_not_found 404 Nenhuma das suas tentativas tem esse id.
candidate_not_found 404 Não tem nenhum candidato com esse id.
test_not_open 409 O teste ainda não está aberto ou já fechou.
already_submitted 409 Este candidato já entregou este teste.
invalid_request 400 Falta um campo ou não tem a forma esperada.
monthly_limit_reached 429 A quota do mês esgotou. As chaves de teste continuam a funcionar.
internal_error 500 Algo correu mal do nosso lado. Tente de novo.

Limites e dados

  • Até 300 pedidos por minuto por chave de servidor. Acima disso, a resposta é 429 sem conteúdo; espere um minuto e tente de novo.
  • As tentativas live e a correção por IA contam para a quota mensal do seu plano. As tentativas iniciadas com uma chave de teste não contam.

Os seus dados

O que guardamos sobre os seus testes e candidatos, durante quanto tempo e como o recuperar.

Testes e as suas perguntas
Guardados até os eliminar ou encerrar a sua conta.
Candidatos
O id que enviar, e um nome e email só se os enviar. Guardados durante um ano após a última vez que o candidato foi visto.
Tentativas e resultados
Respostas, gravações, classificações e eventos de integridade. Guardados durante um ano após o início da tentativa e depois apagados.
Provas de treino
Guardadas durante um ano, apenas para contar a sua utilização. A pontuação chega à sua página no evento completed.
Entregas de webhooks
Guardadas durante 30 dias, no registo de entregas da sua consola.
Utilização da API
Contagens diárias por chave, guardadas durante 400 dias, no ecrã Utilização da sua consola.

Obtenha os resultados a qualquer momento com GET /attempts. Nos planos Growth e Institution também pode transferir os resultados de cada teste em CSV a partir do menu do teste na sua consola: uma linha por tentativa com a classificação de cada pergunta e a resposta do candidato nas perguntas que escreveu. As perguntas do banco da Green Bridge mostram apenas as classificações.

Para apagar um candidato mais cedo:

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"}'

Um resultado que um candidato guarda na sua própria conta Green Bridge passa a pertencer-lhe a partir desse momento. Apagar o candidato ou encerrar a sua conta não o remove.

O proprietário da sua conta pode encerrá-la em Sites e chaves. As chaves e os webhooks param de imediato e tudo o que está acima é apagado no prazo de um dia, por isso transfira primeiro o que precisar.

Os compromissos subjacentes constam de Parceiros e tratamento de dados nos nossos Termos e Condições.

Precisa de algo que os planos não cobrem? Use Contacte-nos no ecrã Plano da sua consola.