Generate Share Links

Generate hosted virtual card links ("open-loop" Send Cards) from your platform. You call one API to create one or more links, then deliver those links to recipients by email, by SMS, or through your own distribution flow. When a recipient opens the link, they land on a Fluz-hosted activation page, verify themselves, and claim a single-load virtual card funded from your account.

📘

What "hosted" / "open-loop" means

A hosted link points to a Fluz-hosted activation page. Open-loop means the recipient claims a network virtual card that can be used at eligible merchants, subject to your program rules.

How it works

  1. Your platform calls generateVCShareLinks with the offer, card limit, quantity, funding source, and delivery method.
  2. Fluz creates one share request and one hosted URL for each requested link.
  3. Delivery depends on shareMethod:
    • GENERATE_URL: Fluz returns the hosted URLs in the API response, and you distribute them yourself.
    • EMAIL: Fluz emails each recipient their link.
    • PHONE_NUMBER: Fluz texts each recipient their link.
  4. The recipient opens the hosted link, signs in, completes verification, and claims the card.
  5. Fluz issues a single-load virtual card to the recipient, funded from the sender's account.

Authentication

All Send Cards share-link operations use the Fluz GraphQL API.

POST https://<your-fluz-api-host>/api/v1/graphql
Authorization: Bearer <access_token>
Content-Type: application/json

Your access token must include the CREATE_SHARE_LINK scope.

{
  "scopes": ["CREATE_SHARE_LINK"]
}

Your account must also have hosted virtual card sending enabled. If your account is not enabled, the API returns a permissions error instructing you to contact your Fluz representative.

Operations

OperationTypePurpose
generateVCShareLinksMutationCreate one or more hosted virtual card links.
getVCShareLinksQueryList and inspect previously generated links.
deactivateVCShareLinksMutationDeactivate generated links.

generateVCShareLinks

Creates quantity hosted share links.

mutation GenerateVCShareLinks($input: GenerateVCShareLinksInput!) {
  generateVCShareLinks(input: $input) {
    shareLinks
  }
}

Input fields

FieldTypeRequiredDescription
cardLimitInt!YesSpend limit and load amount for each card. Must be a whole number and meet the program minimum.
offerIdString!YesUUID v4 of the virtual card offer. The offer must be active and its merchant must be shareable.
quantityInt!YesNumber of links to generate. Fluz creates one distinct hosted URL per unit.
shareMethodShareMethodType!YesDelivery method: GENERATE_URL, EMAIL, or PHONE_NUMBER.
userCashBalanceIdUUIDYesSpend account used to fund the cards. This field is required even though the GraphQL schema may show it as optional.
daysUntilExpirationIntNoNumber of days the link is valid. Minimum is 1. If omitted, the program default is used. The resulting expiration date also becomes the card lock/freeze date after issuance.
recipientListEmail[String]ConditionalRequired when shareMethod is EMAIL. Length must equal quantity. Must be omitted or empty for other delivery methods.
recipientListPhone[String]ConditionalRequired when shareMethod is PHONE_NUMBER. Length must equal quantity. Must be omitted or empty for other delivery methods.

Delivery methods

shareMethodBehaviorRecipient list rule
GENERATE_URLReturns hosted URLs for you to distribute.Do not send recipientListEmail or recipientListPhone.
EMAILSends one email per recipient.Send recipientListEmail; length must equal quantity.
PHONE_NUMBERSends one SMS per recipient.Send recipientListPhone; length must equal quantity.

Validation rules

  • cardLimit must be a whole number and meet the program minimum.
  • offerId must be a valid UUID v4 for an active shareable offer.
  • quantity must be a whole number.
  • When using EMAIL or PHONE_NUMBER, the recipient list length must equal quantity.
  • userCashBalanceId must be a valid spend account owned by the sender's account.
  • Do not include multiple funding sources.
  • Invalid or malformed requests fail validation and create no share links.

Example: generate URLs for your own delivery

mutation GenerateVCShareLinks($input: GenerateVCShareLinksInput!) {
  generateVCShareLinks(input: $input) {
    shareLinks
  }
}
{
  "input": {
    "cardLimit": 25,
    "offerId": "11111111-2222-3333-4444-555555555555",
    "daysUntilExpiration": 30,
    "quantity": 3,
    "shareMethod": "GENERATE_URL",
    "userCashBalanceId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
  }
}

Example: email links to recipients

{
  "input": {
    "cardLimit": 25,
    "offerId": "11111111-2222-3333-4444-555555555555",
    "daysUntilExpiration": 30,
    "quantity": 2,
    "shareMethod": "EMAIL",
    "recipientListEmail": [
      "[email protected]",
      "[email protected]"
    ],
    "userCashBalanceId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
  }
}

Example: text links to recipients

{
  "input": {
    "cardLimit": 25,
    "offerId": "11111111-2222-3333-4444-555555555555",
    "daysUntilExpiration": 30,
    "quantity": 2,
    "shareMethod": "PHONE_NUMBER",
    "recipientListPhone": [
      "+12125550101",
      "+12125550102"
    ],
    "userCashBalanceId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
  }
}

Response

{
  "data": {
    "generateVCShareLinks": {
      "shareLinks": [
        "https://fluz.app/virtual-prepaid-card/3f8a...c1",
        "https://fluz.app/virtual-prepaid-card/9b2d...77",
        "https://fluz.app/virtual-prepaid-card/0c41...e3"
      ]
    }
  }
}

Each value in shareLinks is a hosted URL for one share request.

https://fluz.app/virtual-prepaid-card/{share_request_id}

The API returns the hosted destination URL. If Fluz also creates a short-link wrapper internally, that short URL is not returned by this API.

getVCShareLinks

Use getVCShareLinks to list generated links, retrieve batch and display IDs, inspect delivery targets, and check status.

query GetVCShareLinks($input: GetVCShareLinksInput!) {
  getVCShareLinks(input: $input) {
    senderAppId
    shareRequestBatchId
    shareRequestDisplayId
    shareObjectStatus
    recipientPhone
    recipientEmail
    linkExpirationDate
    virtualCardId
    linkUrl
    shareRequestDetails {
      cardLimit
      offerId
      daysUntilExpiration
      quantity
      shareMethod
      recipientListEmail
      recipientListPhone
      userCashBalanceId
    }
  }
}

Input fields

FieldTypeDescription
shareObjectStatuses[ShareObjectStatus]Filter by status: PENDING, ISSUED, USED, or EXPIRED.
shareRequestBatchIds[String]Return only links in these batches.
shareRequestDisplayIds[String]Return only links with these display IDs.

For the first lookup, filter by shareObjectStatuses. The response includes shareRequestBatchId and shareRequestDisplayId, which you can use for later lookups or deactivation.

Examples

{
  "input": {
    "shareObjectStatuses": ["PENDING", "ISSUED"]
  }
}
{
  "input": {
    "shareRequestBatchIds": ["ABC123", "XYZ789"]
  }
}
{
  "input": {
    "shareRequestDisplayIds": ["SR-000001", "SR-000002"]
  }
}

Response fields

FieldTypeDescription
senderAppIdStringApplication that generated the link.
shareRequestBatchIdStringBatch ID shared by links created in the same generation request.
shareRequestDisplayIdStringHuman-friendly ID for the individual share request.
shareObjectStatusShareObjectStatusCurrent status of the share request.
recipientEmailStringRecipient email, when delivered by email.
recipientPhoneStringRecipient phone number, when delivered by SMS.
linkExpirationDateDateTimeLink expiration date and card lock/freeze date.
virtualCardIdStringIssued virtual card ID after the link is claimed.
linkUrlStringHosted URL for the share request.
shareRequestDetailsShareRequestDetailsOriginal generation settings.

deactivateVCShareLinks

Use deactivateVCShareLinks to expire generated links, for example if a batch was sent in error or an unclaimed link needs to be revoked.

mutation DeactivateVCShareLinks($input: DeactivateVCShareLinksInput!) {
  deactivateVCShareLinks(input: $input)
}

Input fields

FieldTypeDescription
shareRequestBatchIds[String]Deactivate every link in these batches.
shareRequestDisplayIds[String]Deactivate only links with these display IDs.

Example

{
  "input": {
    "shareRequestBatchIds": ["ABC123"]
  }
}

Response

Returns a confirmation string, for example:

3 share requests successfully deactivated!

Deactivating a link prevents an unclaimed link from being claimed. If a card has already been issued, use the appropriate card lifecycle controls to manage that card.

Recipient activation experience

When a recipient opens a hosted link, they are taken to a Fluz-hosted activation page.

  1. The recipient opens the hosted virtual card link.
  2. The recipient signs in or creates an account through the Fluz auth flow.
  3. Existing users complete 2FA before viewing or claiming the card.
  4. If the recipient does not have a billing address on file, they are prompted to add one. A billing address is required for online purchases.
  5. If the card has not been issued yet, the recipient sets a PIN.
  6. Fluz issues the virtual card to the recipient.
  7. Once issued, the recipient can view card details and activity.

If the same user opens a link they already claimed, they can view their card details. If a different user opens a link already claimed by someone else, they are shown an access-denied state after authentication.

Expiration and card freeze

daysUntilExpiration determines the hosted link's validity window.

The resulting expiration date is used for two related behaviors:

  • Before claim: after the expiration date, the link can no longer be claimed.
  • After claim: the expiration date becomes the card lock/freeze date. After that date, the issued card is frozen and can no longer be spent.

If daysUntilExpiration is omitted, the program default is used.

Program rules

Program rules can vary by partner. Confirm the final values for your program with your Fluz representative.

RuleDefault / behavior
Funding sourceSender's spend account.
Daily account spend limit$250,000/day unless your program has a custom limit.
Restaurant transaction buffer25% buffer applies to restaurant transactions.
Restricted merchants/categoriesProgram-specific restrictions may apply.
Recipient support1-888-360-6660 or [email protected].

Status reference

StatusMeaning
PENDINGLink generated and not yet claimed.
ISSUEDRecipient claimed the link and a virtual card was issued.
USEDIssued card has been used.
EXPIREDLink expired or was deactivated.

Common errors

CauseResult
Missing or invalid Bearer tokenRequest is rejected.
Missing CREATE_SHARE_LINK scopeRequest is rejected.
Account does not have hosted card sending enabledPermissions error.
Recipient list length does not equal quantityValidation error; no links are created.
Inactive or non-shareable offerValidation error; no links are created.
Missing or invalid userCashBalanceIdValidation error; no links are created.
Multiple funding sources suppliedValidation error; no links are created.

Notes and limitations

  • This API is for hosted virtual cards only. Hosted gift-card links are not supported.
  • The API returns hosted destination URLs, not short URLs.
  • userCashBalanceId is required in practice.
  • Object type and card type are fixed for this phase and should not be supplied in public API requests.
📘

Please note

  • If your funding source does not have enough funds at the time of the recipient claiming the card, it will fail. Please ensure you have sufficient balances.
  • The phone numbers in recipientListPhone must be a string with no spaces, and it must include the country code at the beginning e.g. +18883606660 where +1 is the country code.