---
title: "Moving from Rest PKI to Rest PKI Core"
description: "Move an application from Rest PKI (pki.rest) to Rest PKI Core: which Rest PKI APIs Rest PKI Core serves as-is, what changes, and the newer APIs to adopt."
canonical: "https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/migrating-from-rest-pki"
locale: "en"
product: "Rest PKI Core"
last_updated: "2026-10-12"
---

# Moving from Rest PKI to Rest PKI Core

[Rest PKI](https://docs.lacunasoftware.com/en-us/articles/rest-pki), the cloud service at [pki.rest](https://pki.rest/), is a legacy product: it still receives bug and security
fixes, but new cloud integrations should use [Rest PKI Core](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core). This guide is for an application already integrated with Rest PKI that
moves to Rest PKI Core, on the SaaS instance at [core.pki.rest](https://core.pki.rest/) or on an [instance of your own](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/on-premises).

Rest PKI Core serves most of the Rest PKI APIs, so the move can happen in two stages:

1. **Point the application at Rest PKI Core.** The Rest PKI APIs it serves keep the same routes and models: your code changes where it gets the
   endpoint and the credential, where your pages initialize Web PKI and, if you created security contexts of your own, where it names them. See
   [Serving your code as-is](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/migrating-from-rest-pki#as-is).
1. **Adopt the newer APIs, at your own pace.** [Signature sessions](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-sessions), [two-step signatures](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/two-step-signatures)
   and [certificate authentication](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/cert-auth) replace the Rest PKI signature and authentication flows, with hosted signing pages, webhooks
   and newer client libraries. See [Moving to the newer APIs](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/migrating-from-rest-pki#newer-apis).

A few Rest PKI APIs have no counterpart on Rest PKI Core: check [What Rest PKI Core doesn't serve](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/migrating-from-rest-pki#not-served) before you start.

## Before you start

* **Get access to an instance.** On the SaaS instance, ask [developer support](mailto:suporte@lacunasoftware.com) for access if your organization
  doesn't have it yet; for an instance of your own, see [Rest PKI Core on-premises](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/on-premises).
* **Create an application and an API key** on the instance's dashboard, with the **Worker** role. Worker covers every Rest PKI API that Rest PKI
  Core serves: signatures, certificate authentication, timestamps, PDF marks and signature inspection. See
  [Create an API key](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/get-started#create-api-key).
* **Plan for the Web PKI license.** With Rest PKI at pki.rest, Web PKI needs no license, even in production. With Rest PKI Core, it does, on the
  SaaS instance as on your own. See [Licensing](https://docs.lacunasoftware.com/en-us/articles/welcome/licensing#rest-pki-core).

## Serving your code as-is

### What Rest PKI Core serves

Rest PKI Core answers these Rest PKI routes with the Rest PKI request and response models:

| Rest PKI feature | Routes |
| --- | --- |
| PAdES signature | `POST Api/PadesSignatures`, `Api/v2/PadesSignatures`, `Api/PadesSignatures/{token}/SignedBytes`, `Api/PadesSignatures/{token}/Finalize`, `Api/v2/PadesSignatures/{token}/SignedBytes` |
| CAdES signature, including co-signing | `POST Api/CadesSignatures`, `Api/v2/CadesSignatures`, `Api/v3/CadesSignatures`, `Api/CadesSignatures/{token}/SignedBytes`, `Api/CadesSignatures/{token}/Finalize`, `Api/v2/CadesSignatures/{token}/SignedBytes`, `Api/CadesSignatures/RequiredHashes` |
| XML signature of the whole document or of an element | `POST Api/XmlSignatures/FullXmlSignature`, `Api/XmlSignatures/XmlElementSignature`, `Api/XmlSignatures/{token}/SignedBytes`, `Api/XmlSignatures/{token}/Finalize` |
| Opening and validating signatures | `POST Api/PadesSignatures/Open`, `Api/CadesSignatures/Open`, `Api/XmlSignatures/Open`, `Api/v2/XmlSignatures/Open` |
| Certificate authentication | `POST Api/Authentications`, `Api/Authentications/{token}/Finalize`, `Api/Authentications/{token}/SignedBytes`; `GET` and `POST Api/Authentication` |
| Opening a certificate | `POST Api/Certificates/Open` |
| PDF marks (printer-friendly versions) | `POST Api/Pdf/AddMarks` |
| Visual representation presets | `GET Api/PadesVisualPositioningPresets/Footnote`, `.../FootnoteBottomUp`, `.../NewPage` |
| Uploading large files | `POST Api/MultipartUploads`, `Api/MultipartUploads/{token}/{partNumber}`, `Api/MultipartUploads/{token}` |
| Timestamps | `POST tsp/{id}` (TSP protocol) and `POST Api/TimestampPlans/{id}/Issue` |
| Signing in the browser with Web PKI's `signWithRestPki()` | `GET` and `POST Api/PendingSignatures/{token}`, `POST Api/PendingSignatures/{token}/Certificate` (called by Web PKI, not by your code) |

The same standard signature policies are available, with the same IDs, such as `StandardPadesSignaturePolicies.PkiBrazil.AdrBasica` and
`StandardCadesSignaturePolicies.PkiBrazil.AdrArquivamento`, and so are the tags of the PDF visual representation, such as `{{name}}` and
`{{br_cpf_formatted}}` (see [PAdES tags](https://docs.lacunasoftware.com/en-us/articles/rest-pki/pades-tags)). The `callbackArgument` of a signature also comes back when it is finished.

### What changes

| | Rest PKI | Rest PKI Core |
| --- | --- | --- |
| **Endpoint** | `https://pki.rest/`, or your on-premises instance | `https://core.pki.rest/` on the SaaS instance, or the address of your own instance's dashboard |
| **Credential** | An access token, generated on the **Control Panel** at pki.rest | An API key of an application with the **Worker** role, created on the dashboard of the instance |
| **Header** | `Authorization: Bearer <access token>` | `X-Api-Key: <API key>`; `Authorization: Bearer <API key>` is also accepted, so a client library that sends the access token as a bearer token works when you give it the API key instead |
| **Web PKI** | Calls `https://restpki.lacunasoftware.com/` by default | Pass the endpoint of Rest PKI Core to `init()` as `restPkiUrl` (see below) |
| **Web PKI license** | Not needed with pki.rest | Needed |
| **Dates on PDF signatures** | **Region and Date** in your account | **Settings** > **Region and Time** on the dashboard |

If your pages sign with Web PKI's `signWithRestPki()`, as the Rest PKI samples do, Web PKI fetches the pending signature from the Rest PKI instance
itself. Tell it where Rest PKI Core is:

```javascript
pki.init({
	restPkiUrl: 'https://core.pki.rest/', // the endpoint of your Rest PKI Core instance
	ready: onWebPkiReady,
});
```

### Client libraries

The Rest PKI client libraries send the access token as `Authorization: Bearer`, and Rest PKI Core accepts an API key sent that way, so an
application can keep its Rest PKI client library at first and only give it the new endpoint and the API key. The Rest PKI Core libraries differ by
language:

| Language | Rest PKI | Rest PKI Core | What the Rest PKI Core library brings |
| --- | --- | --- | --- |
| .NET | `Lacuna.RestPki.Client` | `Lacuna.RestPkiCore.Client` 5.0.0 | It depends on `Lacuna.RestPki.Client` 5.0.0 and shares its namespace, `Lacuna.RestPki.Client`: adding it keeps `RestPkiClient`, the starters, finishers and explorers, `Authentication` and `PdfMarker`, next to `IRestPkiService` for the newer APIs. Both target .NET Standard 2.0 |
| Java | `com.lacunasoftware.restpki:restpki-client` | `com.lacunasoftware.restpki:restpkicore-client` 1.4.0 | A new package, `com.lacunasoftware.restpkicore`, without the Rest PKI classes. Its `RestPkiService` has methods for the Rest PKI routes, such as `startPadesSignature()`, `completePadesSignature()`, `startCadesSignature()`, `startFullXmlSignature()` and `addPdfMarks()`, besides the newer APIs. Both need Java 8 |
| PHP | `lacuna/restpki-client` | `lacuna/restpkicore-client` 1.2.1 | It requires `lacuna/restpki-client` ^2.7.0 and shares its namespace, `Lacuna\RestPki`, so the Rest PKI classes stay available. Its `RestPkiService` covers signature sessions and documents; the PHP sample calls the two-step signature routes through `getRestClient()->post()`, since the library has no method for them |
| Node.js | `restpki-client` | `restpki-core-client` 1.0.2 | Classes generated from the API for each group of routes, including the Rest PKI ones (`PadesSignatureApi`, `CadesSignatureApi`, `XmlSignatureApi`, `PdfApi`, `TimestampApi`, `AuthenticationApi`) and the newer ones (`SignatureApi`, `SignatureSessionsApi`, `DocumentsApi`, `SignatureInspectionApi`), behind a `RestPkiCoreClient` built with `baseUrl` and `apiKey`. It has no starters or finishers |
| Python | `restpki-client` | `restpki-ng-python-client` 0.9.1.1 | Classes generated from the API for each group of routes, including the Rest PKI ones (`PadesSignatureApi`, `CadesSignatureApi`, `XmlSignatureApi`, `PdfApi`, `AuthenticationApi`) and the newer ones (`SignatureApi`, `SignatureSessionsApi`, `DocumentsApi`, `SignatureInspectionApi`), on an `ApiClient` built with the endpoint and the `X-Api-Key` header. See [Python](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/get-started#python) |
| Ruby | `rest_pki` | None: the Ruby sample calls the REST API directly | — |

On .NET, the Rest PKI client 2.2.0 and later share version numbers with `Lacuna.RestPkiCore.Client` and target only .NET Standard 2.0; an
application on 1.24.1 (.NET Framework 3.5 to 4.6) upgrades first. See [.NET](https://docs.lacunasoftware.com/en-us/articles/rest-pki/dotnet#versions) on the Rest PKI
documentation. To set up the Rest PKI Core library for the newer APIs, see [Get started](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/get-started#calling-the-api).

TODO(docs): no page says whether the Rest PKI client libraries for Java, PHP, Node.js, Python and Ruby are supported against Rest PKI Core.

### Security contexts

Rest PKI Core creates the standard security contexts on every instance, with the same IDs as on Rest PKI, so code that passes
`StandardSecurityContexts.PkiBrazil` or `StandardSecurityContexts.LacunaTest` works unchanged:

| Security context | ID |
| --- | --- |
| `PkiBrazil` (ICP-Brasil) | `201856ce-273c-4058-a872-8937bd547d36` |
| `PkiItaly` | `c438b17e-4862-446b-86ad-6f85734f0bfe` |
| `WindowsServer` | `3881384c-a54d-45c5-bbe9-976b674f5ec7` |
| `LacunaTest` (Lacuna Test PKI, for development only) | `803517ad-3bbc-4169-b085-60053a8f6dbf` |

Rest PKI Core adds `PkiBrazilExtended`, `GovBR`, `PkiBrazilWithENotariado` and `PkiBrazilWithGovBrAndENotariado`.

A security context you created yourself on Rest PKI is not carried over: create it again on Rest PKI Core, where users with the **Manager** or
**Admin** role manage the subscription's security contexts, and use its new ID. You can also choose a **Default security context** for the
subscription, in **Settings** > **General settings**, which Rest PKI Core uses when a call names none. See [Security contexts](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts).

### Testing with the Lacuna Test PKI

The [test certificates](https://docs.lacunasoftware.com/en-us/articles/pki-guide/test-certs) work as they did on Rest PKI: name the `LacunaTest` security context in the calls, in
development only. Unlike a Rest PKI on-premises instance, where it might have to be created first, every Rest PKI Core instance creates it when it
starts. See [Rest PKI Core](https://docs.lacunasoftware.com/en-us/articles/pki-guide/test-certs#rest-pki-core) on the test certificates page.

TODO(docs): no page describes a sandbox or test environment of the SaaS instance, nor test API keys for it.

### Timestamps

On Rest PKI Core, timestamps come from **tiers** instead of plans. The `PkiBrazil` tier (ICP-Brasil) has the ID of the Rest PKI plan,
`a402df41-8559-47b2-a05c-be555bf66310` (`StandardTimestampPlans.PkiBrazil`), so `tsp/a402df41-8559-47b2-a05c-be555bf66310` and
`Api/TimestampPlans/a402df41-8559-47b2-a05c-be555bf66310/Issue` keep working on an instance where that tier is enabled, as on the SaaS instance.
These routes also take the tier's name instead of its ID, such as `tsp/PkiBrazil`, and Rest PKI Core adds `api/tsp/{tier}`, where the documented
header is `Authorization: ApiKey <API key>`. See [Requesting timestamps](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/requesting-timestamps).

## What Rest PKI Core doesn't serve

* **XML signatures of detached or online resources**: `Api/XmlSignatures/DetachedResourceXmlSignature` and
  `Api/XmlSignatures/OnlineResourceXmlSignature` (in .NET, `DetachedResourceXmlSignatureStarter` and `OnlineResourceXmlSignatureStarter`) were not
  ported. The source asks users who need them to contact Lacuna: write to [developer support](mailto:suporte@lacunasoftware.com).
* **Account and management APIs**: generating access tokens, managing security contexts, listing signature policies, timestamp plans and
  transactions through the Rest PKI routes (`Api/Account`, `Api/SecurityContexts`, `Api/SignaturePolicies`, `Api/TimestampPlans`,
  `Api/Transactions`, `Api/Users` and others). Rest PKI Core has its own dashboard and APIs for these.
* **System information routes** other than `api/system/info`, such as `Api/System/Cultures`, `Api/System/TimeZones` and `Api/System/Date`.

The remarks of the XML signature API in the source also list `Api/XmlSignatures/Open` as not ported, but Rest PKI Core 5.0.5 serves it, with
`Api/v2/XmlSignatures/Open`.

## Moving to the newer APIs

Once the application runs on Rest PKI Core, replace each Rest PKI flow with its newer equivalent when convenient:

| With Rest PKI | With Rest PKI Core | See |
| --- | --- | --- |
| Start a PAdES, CAdES or XML signature, sign with Web PKI's `signWithRestPki()` on your page, finish it | Create a signature session and redirect the user to the signing page hosted by Rest PKI Core, which uses Web PKI or cloud certificates; get the signed documents through the API or a webhook | [Signature sessions](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-sessions) |
| The same, keeping the signing page in your application | Prepare the signature, sign the hash with Web PKI's `signHash()` on your page, complete it | [Two-step signatures](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/two-step-signatures#signing-with-web-pki) |
| Sign with a key held by your server (the *server key* samples) | Prepare the signature, sign the hash on your server, complete it | [Two-step signatures](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/two-step-signatures#signing-with-a-server-key) |
| `Authentication`: `StartWithWebPkiAsync()`, `signWithRestPki()`, `CompleteWithWebPkiAsync()` | Prepare the authentication, sign the hash with Web PKI's `signHash()`, complete it; the state stays on your page, and reused nonces are rejected | [Certificate authentication](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/cert-auth) |
| Open and validate signatures (`PadesSignatureExplorer`, `CadesSignatureExplorer`, `XmlSignatureExplorer`) | Signature inspection, `PUT api/signature-inspection`, with `validate = true` to validate | [Signature inspection](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-inspection) |
| Request a timestamp | `POST api/tsp/{tier}` | [Requesting timestamps](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/requesting-timestamps) |

PDF marks (`PdfMarker`) have no newer equivalent: keep `Api/Pdf/AddMarks`, which Rest PKI Core serves as-is. The PDF stamp API of Rest PKI Core,
`POST api/pdf/stamp`, does something else: it adds a document timestamp to the PDF. See [Stamps and PDF marks](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/pdf-stamp#marks).

The newer APIs also bring what Rest PKI doesn't have: [webhooks](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/webhooks), [certificate requirements](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-sessions/certificate-requirements),
[PDF/A conversion](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-sessions/pdf-a-conversion), [background processing](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-sessions/background-processing) and verification
codes on the signed documents.

## Comparing the samples

The [PkiSuiteSamples](https://github.com/LacunaSoftware/PkiSuiteSamples) projects have Rest PKI and Rest PKI Core versions of some samples side by
side, which show the same feature before and after the move:

| Feature | Rest PKI sample | Rest PKI Core sample |
| --- | --- | --- |
| PAdES signature on your page with Web PKI | `PadesSignatureRestController` (.NET, Java), `pades-signature-rest` (PHP), `pades-signature-restpki.js` (Node.js) | `PadesSignatureRestCoreController` (.NET), `PadesSignatureCoreController` (Java), `pades-signature-rest-core` (PHP), `pades-signature-core.js` (Node.js), `pades_signature_rest_core.py` (Python, Flask), `pades_signature_rest_core_controller.rb` (Ruby) |
| Batch of PAdES signatures | `batch-pades-signature-restpki.js` (Node.js) | `batch-pades-signature-core.js` (Node.js) |
| Certificate authentication | `AuthenticationRestController` (.NET, Java) | `AuthenticationRestPkiCoreController` (Java) |
| PAdES signature with a server key | `pades-server-key-rest` (PHP) | `PadesServerKeyRestCoreController` (.NET) |
| Hosted signing page | — | `SignatureSessionRestCoreController` and `SignatureSessionPreDefRestCoreController` (.NET, Java), `signature-session-rest-core` (PHP), with `WebhookRestCoreController` (.NET, Java) and `webhook-rest-core` (PHP) |

In the pages, the Rest PKI samples call Web PKI's `signWithRestPki()` with the token; the Rest PKI Core samples read the certificate with
`readCertificate()`, post it to the server, which prepares the signature, then sign the hash with `signHash()`. In .NET the samples keep one
security context helper, `Util.GetSecurityContextId()`, for both products, and the Node.js, PHP, Python and Ruby samples pass the Rest PKI
`StandardSecurityContexts` IDs to Rest PKI Core, since the standard IDs are the same.

No Rest PKI Core sample exists yet for CAdES signatures, XML signatures (including NF-e), opening and validating signatures, or printer-friendly
versions; for those, the application can keep the Rest PKI APIs that Rest PKI Core [serves as-is](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/migrating-from-rest-pki#served-apis).

## See also

* [Get started on integration](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/get-started)
* [Rest PKI Core quick reference](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/quick-reference)
* [Rest PKI quick reference](https://docs.lacunasoftware.com/en-us/articles/rest-pki/quick-reference) (legacy)
