> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/core/digital-signature/ltv.md).

# Add Long-Term Validation (LTV) information for a signature on Server/Desktop

Learn how to enable LTV to digital signature in PDF either signed internally or externally.  The Apryse Server SDK streamlines secure document processing with robust support for C#, C++, Java, JavaScr

{% hint style="info" %}
**Requirements**

*These packages are required to use these features in production. Trial keys have unlimited access to all features*

<a href="https://apryse.com/capabilities#DigitalSignature" class="button primary">Package: Digital Signature</a><a href="https://showcase.apryse.com/digital-signatures" class="button primary">Live demo</a>
{% endhint %}

Long-term Validation (LTV) enables validating a signature on a document at the time it was signed at any time in the future, regardless of any changes made to technology specifications in the future. When LTV is added to a signature, the trusted root certificate that is used has its sign-time status captured and stored inside the PDF document. Regardless of the certificate's expiry or revocation status in the future, the LTV enabled signature guarantees the validity of the signature at the time it was signed.

To add Long-Term Validation (LTV) information for a signature (these examples assume and use an existing DocTimeStamp for LTV addition):

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
VerificationOptions opts = new VerificationOptions(VerificationOptions.SignatureVerificationSecurityLevel.e_compatibility_and_archiving);
opts.AddTrustedCertificate(in_trusted_cert_path);
/* By default, we only check online for revocation of certificates using the newer and lighter 
OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
it may be necessary to enable online CRL revocation checking in order to verify some timestamps
(i.e. those that do not have an OCSP responder URL for all non-trusted certificates). */
opts.EnableOnlineCRLRevocationChecking(true);
VerificationResult timestamp_verification_result = doctimestamp_signature_field.Verify(opts);
if (!doctimestamp_signature_field.EnableLTVOfflineVerification(timestamp_verification_result))
{
	Console.WriteLine("Could not enable LTV for DocTimeStamp.");
	return false;
}
doc.Save(in_outpath, SDFDoc.SaveOptions.e_incremental);
```

{% endcode %}
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
VerificationOptions opts(VerificationOptions::e_compatibility_and_archiving);
opts.AddTrustedCertificate(in_trusted_cert_path);
/* By default, we only check online for revocation of certificates using the newer and lighter 
OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
it may be necessary to enable online CRL revocation checking in order to verify some timestamps
(i.e. those that do not have an OCSP responder URL for all non-trusted certificates). */
opts.EnableOnlineCRLRevocationChecking(true);
VerificationResult timestamp_verification_result = doctimestamp_signature_field.Verify(opts);
if (!doctimestamp_signature_field.EnableLTVOfflineVerification(timestamp_verification_result))
{
	puts("Could not enable LTV for DocTimeStamp.");
	return false;
}
doc.Save(in_outpath, SDFDoc::e_incremental, 0);
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
opts := NewVerificationOptions(VerificationOptionsE_compatibility_and_archiving)
opts.AddTrustedCertificate(inTrustedCertPath)
//       By default, we only check online for revocation of certificates using the newer and lighter 
//   OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
//   it may be necessary to enable online CRL revocation checking in order to verify some timestamps
//   (i.e. those that do not have an OCSP responder URL for all non-trusted certificates).

opts.EnableOnlineCRLRevocationChecking(true)
timestampVerificationResult := doctimestampSignatureField.Verify(opts)
if !doctimestampSignatureField.EnableLTVOfflineVerification(timestampVerificationResult){
		fmt.Println("Could not enable LTV for DocTimeStamp.")
		return false
}
doc.Save(inOutpath, uint(SDFDocE_incremental))
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
VerificationOptions opts = new VerificationOptions(VerificationOptions.SecurityLevel.e_compatibility_and_archiving);
opts.addTrustedCertificate(in_trusted_cert_path);
/* By default, we only check online for revocation of certificates using the newer and lighter 
OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
it may be necessary to enable online CRL revocation checking in order to verify some timestamps
(i.e. those that do not have an OCSP responder URL for all non-trusted certificates). */
opts.enableOnlineCRLRevocationChecking(true);
VerificationResult timestamp_verification_result = doctimestamp_signature_field.verify(opts);
if (!doctimestamp_signature_field.enableLTVOfflineVerification(timestamp_verification_result))
{
	System.out.println("Could not enable LTV for DocTimeStamp.");
	return false;
}
doc.save(in_outpath, SDFDoc.SaveMode.INCREMENTAL, null);
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
async function main() {
	const opts = await PDFNet.VerificationOptions.create(PDFNet.VerificationOptions.SecurityLevel.e_compatibility_and_archiving);
	await opts.addTrustedCertificateUString(in_trusted_cert_path);
	/* By default, we only check online for revocation of certificates using the newer and lighter 
	OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
	it may be necessary to enable online CRL revocation checking in order to verify some timestamps
	(i.e. those that do not have an OCSP responder URL for all non-trusted certificates). */
	await opts.enableOnlineCRLRevocationChecking(true);
	const timestamp_verification_result = await doctimestamp_signature_field.verify(opts);
	if (!(await doctimestamp_signature_field.enableLTVOfflineVerification(timestamp_verification_result))) {
		console.log('Could not enable LTV for DocTimeStamp.');
		return false;
	}
	await doc.save(in_outpath, PDFNet.SDFDoc.SaveOptions.e_incremental);
}
PDFNet.runWithCleanup(main);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
val opts = VerificationOptions(VerificationOptions.SecurityLevel.e_compatibility_and_archiving)
opts.addTrustedCertificate(in_trusted_cert_path)
/* By default, we only check online for revocation of certificates using the newer and lighter
OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However,
it may be necessary to enable online CRL revocation checking in order to verify some timestamps
(i.e. those that do not have an OCSP responder URL for all non-trusted certificates). */
opts.enableOnlineCRLRevocationChecking(true)
val timestamp_verification_result = doctimestamp_signature_field.verify(opts)
if (!doctimestamp_signature_field.enableLTVOfflineVerification(timestamp_verification_result)) {
		println("Could not enable LTV for DocTimeStamp.")
		return false
}
doc.save(in_outpath, SDFDoc.SaveMode.INCREMENTAL, null)
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
PTVerificationOptions* opts = [[PTVerificationOptions alloc] initWithLevel:e_ptcompatibility_and_archiving];
[opts AddTrustedCertificateWithFilePath: in_trusted_cert_path];
/* By default, we only check online for revocation of certificates using the newer and lighter 
OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
it may be necessary to enable online CRL revocation checking in order to verify some timestamps
(i.e. those that do not have an OCSP responder URL for all non-trusted certificates). */
[opts EnableOnlineCRLRevocationChecking: YES];
PTVerificationResult* timestamp_verification_result = [doctimestamp_signature_field Verify: opts];
if (! [doctimestamp_signature_field EnableLTVOfflineVerification: timestamp_verification_result])
{
	NSLog(@"Could not enable LTV for DocTimeStamp.");
	return NO;
}
[doc SaveToFile: in_outpath flags: e_ptincremental];
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
$opts = new VerificationOptions(VerificationOptions::e_compatibility_and_archiving);
$opts->AddTrustedCertificate($in_trusted_cert_path);
/* By default, we only check online for revocation of certificates using the newer and lighter 
OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
it may be necessary to enable online CRL revocation checking in order to verify some timestamps
(i.e. those that do not have an OCSP responder URL for all non-trusted certificates). */
$opts->EnableOnlineCRLRevocationChecking(true);
$timestamp_verification_result = $doctimestamp_signature_field->Verify($opts);
if (!$doctimestamp_signature_field->EnableLTVOfflineVerification($timestamp_verification_result))
{
	echo(nl2br('Could not enable LTV for DocTimeStamp.'.PHP_EOL));
	return false;
}
$doc->Save($in_outpath, SDFDoc::e_incremental);
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
opts = VerificationOptions(VerificationOptions.e_compatibility_and_archiving)
opts.AddTrustedCertificate(in_trusted_cert_path)
# By default, we only check online for revocation of certificates using the newer and lighter 
# OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
# it may be necessary to enable online CRL revocation checking in order to verify some timestamps
# (i.e. those that do not have an OCSP responder URL for all non-trusted certificates).
opts.EnableOnlineCRLRevocationChecking(True)
timestamp_verification_result = doctimestamp_signature_field.Verify(opts)
if not doctimestamp_signature_field.EnableLTVOfflineVerification(timestamp_verification_result):
	print('Could not enable LTV for DocTimeStamp.')
	return False
doc.Save(in_outpath, SDFDoc.e_incremental)
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
opts = VerificationOptions.new(VerificationOptions::E_compatibility_and_archiving);
opts.AddTrustedCertificate(in_trusted_cert_path);
# By default, we only check online for revocation of certificates using the newer and lighter 
# OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
# it may be necessary to enable online CRL revocation checking in order to verify some timestamps
# (i.e. those that do not have an OCSP responder URL for all non-trusted certificates).
opts.EnableOnlineCRLRevocationChecking(true);
timestamp_verification_result = doctimestamp_signature_field.Verify(opts);
if !doctimestamp_signature_field.EnableLTVOfflineVerification(timestamp_verification_result)
	puts('Could not enable LTV for DocTimeStamp.');
	return false;
end
doc.Save(in_outpath, SDFDoc::E_incremental);
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
Dim opts As VerificationOptions = New VerificationOptions(VerificationOptions.SignatureVerificationSecurityLevel.e_compatibility_and_archiving)
opts.AddTrustedCertificate(in_trusted_cert_path)
# By default, we only check online for revocation of certificates using the newer and lighter 
# OCSP protocol as opposed to CRL, due to lower resource usage and greater reliability. However, 
# it may be necessary to enable online CRL revocation checking in order to verify some timestamps
# (i.e. those that do not have an OCSP responder URL for all non-trusted certificates).
opts.EnableOnlineCRLRevocationChecking(True)
Dim timestamp_verification_result As VerificationResult = doctimestamp_signature_field.Verify(opts)

If Not doctimestamp_signature_field.EnableLTVOfflineVerification(timestamp_verification_result) Then
	Console.WriteLine("Could not enable LTV for DocTimeStamp.")
	Return False
End If

doc.Save(in_outpath, SDFDoc.SaveOptions.e_incremental)
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Digital signatures](/core/get-started/samples/digitalsignaturestest.md) Full code sample which demonstrates using the digital signature API to digitally sign, certify, and/or verify PDF documents. Code sample is available in C++, C#, Java, Python, Go, PHP, Ruby & VB.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/core/digital-signature/ltv.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
