---
title: "Academic transcripts"
description: "How to issue digital academic transcripts in Digiploma: the signed XML and its RVHE per Portaria MEC 1095/2018, with signatures collected in Lacuna Signer."
canonical: "https://docs.lacunasoftware.com/en-us/articles/digiploma/api/academic-transcripts"
locale: "en"
product: "Digiploma"
last_updated: "2026-10-11"
---

# Academic transcripts

The digital academic transcript (*histórico escolar digital*), defined by Portaria MEC 1095/2018, is a signed XML file plus its visual
representation, the **RVHE**, a PDF built from a template. Digiploma creates both, collects the signatures in Lacuna Signer and publishes the
transcript for validation.

A **final** transcript is also generated automatically with each diploma, in the [issue and register](https://docs.lacunasoftware.com/en-us/articles/digiploma/api/degrees) and
[issue only](https://docs.lacunasoftware.com/en-us/articles/digiploma/api/emissions) modes. Use this API to issue the other transcripts, or a final transcript on its own.

## Types

| `type` | Meaning |
|---|---|
| `Partial` | Issued at any time while the student is enrolled, as proof of how much of the curriculum has been completed. |
| `Final` | Issued when the student's relationship with the institution ends, for the diploma or an external transfer. |
| `Copy` | Second copy (*segunda via*), in digital form, of a transcript originally issued on paper. The curriculum code and the admission data become optional. |

A partial transcript is refused while the student has a final transcript for the same course that is not canceled. And when any transcript
of a student and course is signed, Digiploma **cancels the older partial transcripts** of that student and course automatically, with the
reason *"Histórico escolar cancelado automaticamente pois um histórico escolar final ou um novo histórico escolar parcial foi emitido"*.

## Before you start

* The organization must be an issuer (type **Emissora** or **Emissora e Registradora**). Otherwise the call fails with
  `SubscriptionOperationNotAllowed`.
* The Signer API key must be set in the organization's **Configurações** (Settings) (`SignerApiKeyNotSet`).
* You need an academic transcript [template](https://docs.lacunasoftware.com/en-us/articles/digiploma/api/templates-and-flows#templates): a one-page, portrait PDF with the institution's header.
* You need the signers: a saved [signature flow](https://docs.lacunasoftware.com/en-us/articles/digiploma/api/templates-and-flows#signature-flows) of type `AcademicTranscript`, or the signers inline
  in each request.

## Create a transcript

`POST /api/academic-transcripts` creates one transcript. To create many from a JSON file, use a [batch](https://docs.lacunasoftware.com/en-us/articles/digiploma/api/batches).

```json
{
  "type": "Partial",
  "academicTranscriptTemplateId": "6a1d9e44-…",
  "documentFlow": {
    "academicTranscriptFlow": [
      { "order": 1, "requiredSignatures": 1, "isCompany": false,
        "signers": [ { "name": "Maria Souza", "email": "maria@ies.edu.br", "cpf": "12345678909" } ] },
      { "order": 2, "requiredSignatures": 1, "isCompany": true, "companyIdentifier": "12345678000195",
        "signers": [ { "name": "João Lima", "email": "joao@ies.edu.br", "cpf": "98765432100" } ] }
    ]
  },
  "academicTranscript": {
    "aluno": { … },
    "dadosCurso": { … },
    "iesEmissora": { … },
    "historicoEscolar": { "codigoCurriculo": "…", "elementosHistorico": [ … ], "situacaoAtualDiscente": { … }, … }
  }
}
```

| Field | Required | Description |
|---|---|---|
| `type` | Yes | `Partial`, `Final` or `Copy`. |
| `academicTranscriptTemplateId` | Yes | The academic transcript template. |
| `academicTranscript` | Yes | The MEC data: the student (`aluno`), the course (`dadosCurso`), the issuing institution (`iesEmissora`) and the transcript itself (`historicoEscolar`). `historicoEscolar.dataEmissaoHistorico` and `horaEmissaoHistorico` default to the current date and time. |
| `documentFlowId` | One of the two | A saved signature flow of type `AcademicTranscript`. |
| `documentFlow` | One of the two | The signers inline. Only `academicTranscriptFlow` may be filled. Takes precedence over `documentFlowId`. |
| `newFolderName` | No | Creates a Signer folder with this name for the document. Takes precedence over `signerFolderId`. |
| `signerFolderId` | No | An existing Signer folder. |

A complete example of the data is in the [JSON sample file](https://www.digiploma.com.br/assets/files/academic-transcript-template2.json).
The data is validated against the MEC XML schema.

**Signers.** The flow needs at least one institutional signature (`isCompany: true`, an e-CNPJ certificate), or the call fails with
`DocumentFlowIssuerInstitutionSignatureRequired`. The representatives (e-CPF) sign first, in the order of their `order` values, in a step
named *Secretaria acadêmica*; the institution signs last, in a step named *Instituição*. Only the first institutional rule is used. Final
transcripts and second copies require A3 certificates, unless the instance disables that requirement.

**The response** is `{success, academicTranscriptId, errors}`:

> **Warning: Check success, not just the HTTP status**
>
> Failures that happen while the transcript is generated return **HTTP 200** with `"success": false`, and the processing log in Portuguese in
> `errors`. That includes a duplicate validation code and a partial transcript refused because of an existing final one. See
> [Creation results](https://docs.lacunasoftware.com/en-us/articles/digiploma/api#creation-results).

The **validation code** is computed from the student, the course, the institution and the issue date and time (to the minute), in the format
`{issuer MEC code}.{12 hexadecimal characters}`. Two transcripts of the same student and course issued in the same minute get the same code,
and the second one is refused as a duplicate.

## Statuses

| `status` | Meaning |
|---|---|
| `Created` | Created; waiting for signatures. |
| `Active` | Signed: the transcript is valid. |
| `CanceledTemporarily` | Temporarily canceled. Can be restored. |
| `Canceled` | Canceled. |

## Cancel, suspend or restore

**`POST /api/academic-transcripts/{id}/cancellation`** cancels a transcript, with a `reason` of up to 500 characters:

```json
{ "reason": "Emitido com dados incorretos" }
```

If the transcript is not signed yet, its document is deleted from Signer and it can never be restored. A transcript that is already
canceled fails with `AcademicTranscriptAlreadyCanceled`.

**`POST /api/academic-transcripts/{id}/status`** changes the status, with a required `reason`:

| `status` | Allowed when |
|---|---|
| `Canceled` | The transcript is not canceled yet. Same effect as `/cancellation`. |
| `CanceledTemporarily` | The transcript is signed. |
| `Active` (restore) | The transcript is `CanceledTemporarily` and signed (`AcademicTranscriptNotSignedCannotBeRestored`). |

Any other change fails with `AcademicTranscriptInvalidStatus`. Both operations require the `UpdateAcademicTranscript` permission.

## Download the files

| Document | Base64 | Ticket | Direct download | Available when |
|---|---|---|---|---|
| Signed XML | `GET /{id}/xml-b64` | `GET /{id}/xml-ticket` | `GET /{id}/xml` | The transcript is `Active` (`AcademicTranscriptNotValid`). For a ticket, checked when it is downloaded. |
| RVHE | `GET /{id}/visual-representation-b64` | `GET /{id}/visual-representation-ticket` | — | Always. |

All paths are relative to `/api/academic-transcripts`. See [Downloads and tickets](https://docs.lacunasoftware.com/en-us/articles/digiploma/api#downloads-and-tickets).

## Replace the visual representation

`POST /api/academic-transcripts/{id}/visual-representation` replaces the RVHE of a transcript that is not canceled, from another academic
transcript template (`templateId`) or from an [uploaded](https://docs.lacunasoftware.com/en-us/articles/digiploma/api#uploads) PDF in portrait orientation (`uploadId`). The signed XML is not
affected. It requires the `UpdateDocumentVisualRepresentation` permission (**Administrador** and **Gerente** roles).

## Read and search

* `GET /api/academic-transcripts/{id}` returns the transcript, with `degreeId` when it was generated with a diploma.
* `GET /api/academic-transcripts/{id}/history` returns the status changes, newest first.
* `GET /api/academic-transcripts` returns a page of transcripts. Besides the [paging parameters](https://docs.lacunasoftware.com/en-us/articles/digiploma/api#pagination), it filters by
  `Status`, `BatchId`, creation date (`StartDateUtc` inclusive, `EndDateUtc` exclusive), `IsSigned=true` (signed transcripts, including
  canceled ones) and `Q` (student's CPF, name or social name, or course). Results are sorted by update date.

## Validate a transcript

* `GET /api/academic-transcripts/codes/{code}` validates a transcript of your own organization, with the API key.
* `GET /api/academic-transcripts/{code}/validation` is the **public** validation. See [Public validation](https://docs.lacunasoftware.com/en-us/articles/digiploma/api/validation).

## Webhooks

| Event | When |
|---|---|
| `AcademicTranscriptCreated` | The transcript was created (not sent when it is generated with `POST /api/degrees/{id}/academic-transcript`). |
| `AcademicTranscriptConcluded` | The transcript was signed, **or restored**. |
| `AcademicTranscriptCanceled` | The transcript was canceled, including the automatic cancellation of older partial transcripts. |
| `AcademicTranscriptCanceledTemporarily` | The transcript was suspended. |

See [Webhooks](https://docs.lacunasoftware.com/en-us/articles/digiploma/api/webhooks) for the payloads.

## Operation reference

| Operation | Description |
|---|---|
| `POST /api/academic-transcripts` | Create a transcript |
| `GET /api/academic-transcripts` | List transcripts |
| `GET /api/academic-transcripts/{id}` | Get a transcript |
| `GET /api/academic-transcripts/{id}/history` | Get the status history |
| `POST /api/academic-transcripts/{id}/cancellation` | Cancel a transcript |
| `POST /api/academic-transcripts/{id}/status` | Cancel, suspend or restore a transcript |
| `GET /api/academic-transcripts/{id}/xml`, `…/xml-b64`, `…/xml-ticket` | Download the signed XML |
| `GET /api/academic-transcripts/{id}/visual-representation-b64`, `…/visual-representation-ticket` | Download the RVHE |
| `POST /api/academic-transcripts/{id}/visual-representation` | Replace the RVHE |
| `GET /api/academic-transcripts/codes/{code}` | Validate a transcript of your organization |
| `GET /api/academic-transcripts/{code}/validation`, `…/validation/visual-representation`, `…/validation/xml` | [Public validation](https://docs.lacunasoftware.com/en-us/articles/digiploma/api/validation) |
