API REST v1

Documentação da API

O GIRA Sign é independente de qualquer sistema consumidor. Qualquer aplicação pode criar envelopes, acompanhar assinaturas e receber webhooks usando uma API Key da sua organização.

Autenticação

Envie a API Key no header Authorization: Bearer gira_live_… (produção) ou gira_test_… (sandbox). O ambiente é derivado da chave; dados de sandbox e produção são isolados. Base URL: {origem}/api/v1.

curl -H "Authorization: Bearer gira_live_xxx" https://girasign.app/api/v1/me

Criar e enviar um envelope

POST /api/v1/envelopes
Idempotency-Key: pedido-98272
{
  "name": "Contrato de prestação de serviços",
  "signing_order": "sequential",
  "external_source": "meu-erp",
  "external_id": "contract_98272",
  "metadata": { "customer_id": 42 },
  "documents": [{ "name": "Contrato", "file_base64": "JVBERi0x..." }],
  "signers": [
    { "name": "Maria Silva", "email": "maria@exemplo.com", "signer_role": "contractor", "order_index": 0 },
    { "name": "João Souza",  "email": "joao@exemplo.com",  "signer_role": "contracted", "order_index": 1 }
  ],
  "send": true
}

A resposta inclui signing_links — um link individual, aleatório e revogável por signatário. Você decide como entregá-los (e-mail, WhatsApp, portal próprio).

Endpoints

MétodoRotaDescriçãoEscopo
GET/meOrganização, ambiente e escopos da chave.—
POST/documentsEnvia um PDF (base64). Retorna id e SHA-256.documents:write
GET/documents/{id}Detalhe do documento e versões.documents:read
POST/envelopesCria envelope com documentos (id ou base64) e signatários. `send: true` já envia e devolve os links.envelopes:write
GET/envelopesLista com filtros status, external_source, external_id.envelopes:read
GET/envelopes/{id}Detalhe com signatários e documentos.envelopes:read
POST/envelopes/{id}/sendEnvia e gera links individuais.envelopes:write
POST/envelopes/{id}/cancelCancela e revoga todos os links. Body: { reason }.envelopes:write
GET/envelopes/{id}/auditTrilha de auditoria encadeada por hash.envelopes:read
GET/envelopes/{id}/evidenceEventos de assinatura (IP, UA, consentimento, hashes).envelopes:read
GET/envelopes/{id}/completed-documentURLs temporárias (10 min) do PDF final e do certificado.documents:read
GET/templatesLista modelos.templates:read
POST/templatesCria modelo a partir de PDF.templates:write
POST/templates/{id}/envelopesCria envelope a partir de modelo.envelopes:write
GET/webhooksLista endpoints do ambiente.webhooks:manage
POST/webhooksCria endpoint (retorna secret uma única vez).webhooks:manage
GET/webhooks/{id}/deliveriesHistórico de entregas e tentativas.webhooks:manage
GET/eventsÚltimos eventos de domínio do ambiente.envelopes:read

Idempotência, limites e erros

Em requisições POST, envie Idempotency-Key; a mesma chave com o mesmo payload devolve a resposta original (Idempotent-Replayed: true); payload diferente retorna 422 idempotency_mismatch. O limite padrão é 60 req/min por chave (429 rate_limited). Erros seguem { "error": { "code", "message" }, "request_id" }.

Webhooks

Cada entrega é um POST JSON com os headers X-Gira-Event, X-Gira-Delivery, X-Gira-Timestamp e X-Gira-Signature (sha256=HMAC(secret, timestamp + "." + body)). Valide a assinatura e rejeite timestamps antigos. Falhas (não 2xx) são reenviadas com backoff exponencial até 8 tentativas.

document.createddocument.sentdocument.openedidentity.verifiedauthentication.completedconsent.acceptedsignature.completeddocument.completeddocument.rejecteddocument.expiredevidence.generatedenvelope.createdenvelope.sentenvelope.viewedenvelope.completedenvelope.declinedenvelope.cancelledenvelope.expiredsigner.viewedsigner.signedsigner.declined
// Node.js — verificação
const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(ts + "." + rawBody).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sigHeader))) return res.status(401).end();

Infraestrutura própria de assinatura (GIRA Sign Electronic Signature Infrastructure)

O GIRA Sign opera infraestrutura própria de identidade, autenticação, assinatura, criptografia, integridade, auditoria, evidências, armazenamento e verificação. Nenhum fluxo central depende de plataformas externas de assinatura ou certificação. São oferecidos dois níveis: GIRA Sign Basic (assinatura eletrônica simples) e GIRA Sign Advanced (assinatura eletrônica avançada, com credencial criptográfica do signatário via WebAuthn/Passkey, chave privada mantida no dispositivo).

O GIRA Sign não integra a ICP-Brasil, não emite assinatura eletrônica qualificada e não utiliza carimbo do tempo de autoridade terceira. Os horários são timestamps registrados pelo GIRA Sign (relógio do servidor, em UTC, com fuso e horário local do signatário também registrados).

Vinculação criptográfica assinatura ↔ documento

Antes de assinar, o servidor emite um desafio vinculado ao documento e à transação. O signatário confirma o consentimento expresso e, no nível Advanced, a credencial do dispositivo assina o desafio (ES256/EdDSA conforme o autenticador).

challenge = {
  transaction_id, envelope_id, signer_id,
  document_hash,            // SHA-256 do documento apresentado
  document_hashes: [...],   // um por documento do envelope
  nonce,                    // CSPRNG
  timestamp,                // UTC
  consent_version, policy_version,
  operation_type: "signature"
}
challenge_hash = SHA-256(canonical_json(challenge))

São armazenados: desafio, hash do desafio, assinatura criptográfica, credential_id, referência da chave pública, algoritmo e resultado da validação.

Cadeia de auditoria append-only

Nenhum evento pode ser alterado ou excluído — nem por administradores. Correções são registradas como novo evento correction.recorded referenciando o evento anterior.

event_hash[n] = SHA-256( canonical_json(event[n]) + event_hash[n-1] )

Cada evento guarda event_id, transaction_id, ator, UTC, horário local, fuso, tipo, payload_hash, previous_event_hash e event_hash.

Pacote de evidências e verificação offline

Cada transação concluída gera um pacote independente (GS-AAAA-NNNNNN.zip) com: original.pdf, signed.pdf, certificate.pdf, manifest.json, identity.json, consent.json, authentication.json, signature.json, audit-trail.json, evidence.json, hashes.txt e um leia-me de verificação.

O manifest.json contém o SHA-256 de todos os componentes e uma atestação da plataforma (ES256) — distinta da assinatura do signatário. A chave pública fica em /api/public/girasign-keys.

# 1. conferir hashes dos arquivos
sha256sum signed.pdf certificate.pdf original.pdf   # comparar com hashes.txt

# 2. conferir o manifesto
sha256sum manifest.json                             # comparar com manifest_sha256

# 3. validar a atestação da plataforma (ES256, base64url)
#    mensagem = JSON canônico de manifest.payload
#    chave    = /api/public/girasign-keys  (JWK, kid no manifesto)

# 4. reconstruir a cadeia de auditoria a partir de audit-trail.json
#    event_hash[n] = SHA-256(canonical_json(event[n]) + event_hash[n-1])

Verificação pública

Qualquer pessoa pode verificar em /verify (por ID da transação, código do envelope ou código de verificação) ou diretamente em /verify/{transaction_id} — o mesmo endereço do QR Code impresso no documento final. Também é possível enviar um PDF: o SHA-256 é calculado no navegador e comparado com os registros; o arquivo não é armazenado.

O verificador informa existência da transação, integridade dos documentos, status e nível da assinatura, identidade parcialmente mascarada, método de autenticação, integridade da cadeia de auditoria, situação da credencial e versão das evidências.