Scanning Passes

To verify a pass, you will need to do the following:

  1. Obtain the barcode on the pass with a QR scanner.
  2. Use the barcode to call the GET /v0/scan endpoint.

Obtaining a Barcode

You will need to use a QR scanner to scan the barcode included on the pass.

There are many libraries to scan QR codes for both web browsers and mobile,
but ethpass’s example
using qr-scanner is a good sample to reference.

The result of the QR scan should yield a barcodeSignature which you can use to verify the pass via the GET /v0/scan API.

Scanning a Pass

Once you have obtained the barcode on the pass, you simply need to call the GET /v0/scan endpoint with the barcode signature.

const barcode = "0xe49383c69c2f0426877a5086b8113c6d9db200abc";

const response = await fetch(
  `https://api.ethpass.xyz/api/v0/scan?data=${barcode}`,
  {
    headers: new Headers({
      "content-type": "application/json",
      "X-API-KEY": "YOUR_SECRET_API_KEY",
    }),
  }
);

A successful scan will return pass details, a decoded barcode message (if included), and information about the nfts linked to the pass.

📘

Note

A successful scan DOES NOT mean a pass is valid. Instead, the scan result will return information to be handled by the client.

Interpreting the Scan Result

To properly verify the scan result, we suggest checking two attributes:

  1. expiredAt / expiredAction on the pass
  2. scanResult information about the linked Policies or NFT

1. Asset ownership check

If you scan a pass, the response will include a scanResult object that provides further information about the validation of assets.

📘

Info

Our API considers a pass invalid if the requirements of either condition are not met.:

The scanResult object will include a boolean property called valid at the parent level, which can be used to quickly identify whether the ownership conditions were met.

For passes linked to an NFT, the validity is determined in real-time by reading data from the smart contract and verifying the ownership of that specific NFT.

For passes linked to policies, the evaluation process follows the same approach as our API endpoints for handling validations. You can refer to our policies/validate guide for more details on interpreting the results.

📘

Info

The terms "satisfiesAllPolicies" and "valid" are synonyms and can be used interchangeably.

2. Checking Pass Expiration

To confirm a pass has not expired, you can check the expiredAt value in the result.

If this value exists, the pass has been expired, and the expiredAction on the result can provide more details on the reason.

📘

Tip

If you are testing and developing against passes you created with ethpass APIs, you can avoid the QR scanning step by using
GET /v0/passes/{passId} to fetch the pass, obtaining the barcodeSignature from the response, and supplying this to the GET /v0/scan API.

const passId = "f664196b-035a-454d-90c4-ab0adc107981";

const response = await fetch(
  `https://api.ethpass.xyz/api/v0/passes/${passId}`,
  {
    method: "POST",
    body: JSON.stringify(payload),
    headers: new Headers({
      "content-type": "application/json",
      "X-API-KEY": "YOUR_SECRET_API_KEY",
    }),
  }
);

const pass = response.json();
const barcodeSignature = pass.barcodeSignature;

const response = await fetch(
  `https://api.ethpass.xyz/api/v0/scan?data=${barcodeSignature}`,
  {
    headers: new Headers({
      "content-type": "application/json",
      "X-API-KEY": "YOUR_SECRET_API_KEY",
    }),
  }
);

Performing a Dry Run

The dryRun parameter in the API allows you to perform a simulation of a scan without actually recording the results in the database. This is a useful feature for testing and validation purposes, as it enables you to preview the data contained in a scan before marking it as valid. With this parameter set to true, the API will scan a pass and return the extracted information, but it will not be recorded as a valid scan in the database.

const barcode = "0xe49383c69c2f0426877a5086b8113c6d9db200abc";

const response = await fetch(
  `https://api.ethpass.xyz/api/v0/scan?data=${barcode}&dryRun=true`,
  {
    headers: new Headers({
      "content-type": "application/json",
      "X-API-KEY": "YOUR_SECRET_API_KEY",
    }),
  }
);