> ## Documentation Index
> Fetch the complete documentation index at: https://developers.pcibooking.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Send CVV Capture Link

> Send a Card By Link request via email or SMS with a link to a secure CVV capture form.

<Card title="CVV Capture Guide" icon="book" href="/capture-cards/cvv-capture">
  Collect CVV from cardholders via hosted forms
</Card>

Use this endpoint to send a secure CVV capture link to a cardholder who has already provided their card details. The cardholder clicks the link to enter only their CVV, which PCI Booking combines with the original card data to create a new token. This is useful when you already have a stored card token but need the CVV for a subsequent transaction.

<Warning>
  This operation **duplicates** the original token. Once the cardholder enters the CVV, PCI Booking creates a new token with the original card details plus the captured CVV. The original token remains unchanged. Delete it if no longer needed, otherwise it will continue to incur monthly storage fees.
</Warning>

## Error Responses

| Code  | HTTP Status | Condition                                                                                |
| ----- | ----------- | ---------------------------------------------------------------------------------------- |
| -179  | 400         | Validation error: missing required fields, invalid field format, or malformed JSON body. |
| -1003 | 401         | Missing or invalid API key in the `Authorization` header.                                |
| -1003 | 401         | `SenderID` does not match the identity associated with the API key.                      |
| -150  | 500         | Internal system error while creating the CVV request.                                    |

## Parameter Constraints

| Parameter                 | Constraint                               |
| ------------------------- | ---------------------------------------- |
| `RequestTTL`              | Integer, range 1 to 24 (hours).          |
| `Destination`             | Required. Max 255 characters.            |
| `RecipientName`           | Required. Max 70 characters.             |
| `SenderReference`         | Max 50 characters.                       |
| `Description`             | Max 50 characters.                       |
| `CustomHeaderText`        | Max 1000 characters.                     |
| `CustomFooterText`        | Max 1000 characters.                     |
| `CustomerSupportPhone`    | Max 20 characters.                       |
| `CustomerSupportEmail`    | Max 50 characters.                       |
| `CustomerSupportLink`     | Max 255 characters. Must be a valid URL. |
| `CustomerSupportLinkText` | Max 100 characters.                      |
| `LogoTitle`               | Max 100 characters.                      |
| `SiteTitle`               | Max 40 characters.                       |

## Parameters

### Headers

<ParamField header="Authorization" type="string" required>
  Your API key prefixed with `APIKEY`. Example: `APIKEY your-api-key`. See the [Authentication guide](/getting-started/authentication).
</ParamField>

### Request Configuration

<ParamField body="SenderID" type="string" required>
  The user ID of the booker.
</ParamField>

<ParamField body="OriginCardUri" type="string" required>
  The card URI is the resource identifier for the card location within PCI Booking.
</ParamField>

<ParamField body="Language" type="string" default="EN">
  The form's language in ISO 639-1 (2-letter) format. See [supported languages](/account-setup/custom-translations#supported-languages). If an unsupported language is received, English will be displayed. Languages can be added through the user's control panel.
</ParamField>

<ParamField body="Css" type="string">
  The CSS resource name. Follow the guide on [managing stylesheets](/account-setup/stylesheets). If not provided, PCI Booking will apply the [default CSS](/account-setup/stylesheets).
</ParamField>

<ParamField body="CallBackURL" type="string">
  A URL where PCI Booking will push the status of the request.
</ParamField>

<ParamField body="RequestTTL" type="integer" required>
  The number of hours the request will be valid for. Minimum 1 hour, maximum 24 hours.
</ParamField>

### Delivery

<ParamField body="DestinationType" type="string" required>
  How to send the link to the card capture form. Values: `email` or `sms`.
</ParamField>

<ParamField body="Destination" type="string" required>
  The destination email address or phone number. Phone numbers should be formatted as international dial numbers: `Country code + area code + phone number`.
</ParamField>

<ParamField body="RecipientName" type="string" required>
  The recipient's name. Max 70 characters.
</ParamField>

<ParamField body="Description" type="string">
  Free text description of this request. Max 50 characters.
</ParamField>

<ParamField body="SenderReference" type="string">
  A reference value that can be used to query for this card token.
</ParamField>

### Transaction Details

<ParamField body="Amount" type="double">
  The transaction amount. Required if `Currency` is provided.
</ParamField>

<ParamField body="Currency" type="string">
  The transaction currency in ISO 4217 (3-letter) format. Required if `Amount` is provided. An incorrect value returns error code `401 BAD DATA`.
</ParamField>

### Branding

<Info>
  `CustomerSupportLink`, `CustomerSupportLinkText`, `CustomerSupportEmail`, and `CustomerSupportPhone` can also be set in your [account settings](https://users.pcibooking.net/booker/Login). Values provided in the request override the account defaults.
</Info>

<Note>
  URLs in the request body (e.g. `ClientLogoURL`, `Success`, `Failure`) should **not** be URL-encoded, since they are sent in JSON, not as query parameters.
</Note>

<ParamField body="ClientLogoURL" type="string">
  URL to the logo displayed in the Card By Link email and landing page. Submit with a null value to hide the logo. If not supplied, the logo from your Booker profile in the portal is used. Images must be publicly accessible via HTTPS URL.
</ParamField>

<ParamField body="LogoTitle" type="string">
  The title of the logo. If not provided, the booker name from the portal is used. Submit with a null value to hide the logo title. Max 100 characters.
</ParamField>

<ParamField body="FaviconURL" type="string">
  URL to the favicon displayed in the Card By Link landing page. If not supplied, the browser default favicon is used. Images must be publicly accessible via HTTPS URL in ico or png format, size 16x16 or 32x32.
</ParamField>

<ParamField body="SiteTitle" type="string">
  The page title to be displayed. Max 40 characters.
</ParamField>

<ParamField body="CustomHeaderText" type="string">
  Text displayed in the header of the message to the recipient. Max 1000 characters. If `RecipientName`, `Amount`, and `Currency` placeholders are not listed in the `CustomHeaderText` or in the [portal customizations](/account-setup/card-by-link-templates) but are provided in the request parameters, they will still be displayed in the email.
</ParamField>

<ParamField body="CustomFooterText" type="string">
  Text displayed in the footer of the message to the recipient. Max 1000 characters. If `CustomerSupportEmail` and `CustomerSupportPhone` placeholders are not listed in the `CustomFooterText` or in the [portal customizations](/account-setup/card-by-link-templates) but are provided in the request parameters, they will still be displayed in the email.
</ParamField>

<ParamField body="CustomerSupportPhone" type="string">
  Phone number displayed in the email and landing page. Max 20 characters.
</ParamField>

<ParamField body="CustomerSupportEmail" type="string">
  Email address displayed in the email and landing page. Max 50 characters.
</ParamField>

<ParamField body="CustomerSupportLink" type="string">
  URL for customer support displayed in the email and landing page. Max 255 characters. Required if `CustomerSupportLinkText` is provided.
</ParamField>

<ParamField body="CustomerSupportLinkText" type="string">
  Display name for the customer support URL in the email and landing page. Max 100 characters. Required if `CustomerSupportLink` is provided.
</ParamField>

### Redirect URLs

<ParamField body="Success" type="string">
  URL where a successful response will be redirected to. See [setting up success/failure redirection pages](/account-setup/success-and-failure-urls).
</ParamField>

<ParamField body="Failure" type="string">
  URL where a failed response will be redirected to. See [setting up success/failure redirection pages](/account-setup/success-and-failure-urls).
</ParamField>

<RequestExample>
  ```javascript Node.js theme={null}
  const response = await fetch('https://service.pcibooking.net/api/cardrequest/duplicate', {
    method: 'POST',
    headers: {
      'Authorization': 'APIKEY your-api-key',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      SenderID: 'myhotel',
      OriginCardUri: 'https://service.pcibooking.net/api/payments/paycard/d919fe8ee51c4adbbbc22cef85e736a6',
      DestinationType: 'email',
      Destination: 'guest@example.com',
      RecipientName: 'Jane Smith',
      RequestTTL: 12,
      Language: 'en',
      SenderReference: 'booking-12345',
      Description: 'CVV for reservation #12345',
      Amount: 250.00,
      Currency: 'USD',
      Success: 'https://yoursite.com/success',
      Failure: 'https://yoursite.com/failure'
    })
  });

  const requestUri = response.headers.get('Location');
  console.log('Request URI:', requestUri);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://service.pcibooking.net/api/cardrequest/duplicate',
      headers={
          'Authorization': 'APIKEY your-api-key',
          'Content-Type': 'application/json'
      },
      json={
          'SenderID': 'myhotel',
          'OriginCardUri': 'https://service.pcibooking.net/api/payments/paycard/d919fe8ee51c4adbbbc22cef85e736a6',
          'DestinationType': 'email',
          'Destination': 'guest@example.com',
          'RecipientName': 'Jane Smith',
          'RequestTTL': 12,
          'Language': 'en',
          'SenderReference': 'booking-12345',
          'Description': 'CVV for reservation #12345',
          'Amount': 250.00,
          'Currency': 'USD',
          'Success': 'https://yoursite.com/success',
          'Failure': 'https://yoursite.com/failure'
      }
  )

  request_uri = response.headers.get('Location')
  print('Request URI:', request_uri)
  ```
</RequestExample>

## Response

**201** - Empty body. A `Location` header is returned with the URI for this card request. Use this URI to [retrieve the request status](/api-reference/tokenize-cards/cotp-retrieve-request) or [delete the request](/api-reference/tokenize-cards/cotp-delete-request).

<Info>
  Remember to set the [CVV Retention Policy](/capture-cards/cvv-retention-policy) on the new token once the CVV is captured.
</Info>

<ResponseExample>
  ```text 201 theme={null}
  Empty response body. The Location header contains the request URI:
  Location: https://service.pcibooking.net/api/payments/paycard/CardForm/xLoat3F385vvFRbgI2usOeuXKXQoB8kv
  ```

  ```json 400 theme={null}
  {
      "code": -179,
      "message": "Bad input parameter",
      "moreInfo": "Bad input data",
      "errorList": [
          "Bad json format"
      ]
  }
  ```

  ```json 401 theme={null}
  {
      "code": -1003,
      "message": "Not authorized to access this resource",
      "moreInfo": "Bad or missing authorization data, expected APIKEY",
      "errorList": null
  }
  ```
</ResponseExample>
