POAP Moments - MVP

This product is in development and is not intended to be used in a production environment.

Note: The current version of this API is open to all users. However, we are in the process of implementing an authentication system that will require client credentials for write operations. As a result, to upload new Moments in the near future, it will be necessary for you to request and obtain your own set of credentials. Please bear this in mind as you continue to use our services.

Alpha Access

In order to get access to this service, you must first obtain your credentials with the POAP Integrations Team.

Obtaining your JWT

After acquiring access to your API, the next step is to retrieve your JWT (JSON Web Token) which is necessary for utilizing this API. You can do this by executing the following request:

curl --request POST \
  --url https://poapauth.auth0.com/oauth/token \
  --header 'content-type: application/json' \
  --data '{"client_id":"<CLIENT_ID>","client_secret":"<CLIENT_SECRET>","audience":"https://moments.poap.tech","grant_type":"client_credentials"}'

Please be aware that you must replace <CLIENT_ID> and <CLIENT_SECRET> with your actual credentials.



  "id": "426b54f8-4460-4917-9c85-64588dcf0c96",
  "author": "0x7CE5368171cC3D988157d7dab3D313d7bd43de3e",
  "createdOn": "2023-04-13T23:10:13.060Z",
  "dropId": 10000,
  "description": "this is an example",
  "medias": {
    "key": "45b365dd-5ad4-4fc8-b43e-e6b70d2512e1",
    "mimeType": "image/png",
    "status": "PROCESSED",
    "gateways": [
        "type": "image/png",
        "url": "https://cdn.media.poap.tech/45b365dd-5ad4-4fc8-b43e-e6b70d2512e1"
    "hash": "a519802b7a5c796e083b1452ca0ca855f4746a9c1aaf27780ff8e34b58904000"
  • media: An object containing information about the media content associated with the Moment, such as the following:
    • key: A unique identifier for the media file.
    • mimeType: The MIME type of the media file, indicating its format (e.g., "image/png" for a PNG image).
    • status: The processing status of the media file, indicating whether it has been successfully processed or is still pending. Possible values are IN_PROCESS, PROCESSED or FAILED.
    • gateways: A list of URLs where the media file can be accessed and downloaded.
    • hash: A unique hash value representing the media file's content, generated using a SHA-256. This helps ensure the file's integrity and authenticity.
    • location: A custom protocol URL ("poap://...") that points to the media file's location.
  • id: A unique identifier (UUID) for the Moment, used to distinguish it from other Moments.
  • author: The Ethereum account address of the Moment's creator.
  • createdOn: The timestamp indicating when the Moment was created, in ISO 8601 format.
  • dropId: The identifier of the Drop to which the Moment is associated.

Uploading a Moment

This guide provides a step-by-step process for uploading new Moments using any programming language or platform. The steps are focused on the required API endpoints and the data needed for each request.

All steps below will add the Authorization: Bearer <JWT> header, please, be aware of replacing <JWT> with the token you’ve obtained in the previous step.


  1. Get a media upload URL: For uploading a Moment, you will need to first upload the files to a bucket, to obtain an upload url:

Make a POST request to the /moments/media-upload-url endpoint to retrieve a signed URL for uploading the media file.

curl -X POST "https://moments.poap.tech/moments/media-upload-url" -H 'Authorization: Bearer <JWT>'

The response will contain the signed URL and the media key:

  "url": "<SIGNED_URL>",
  "key": "<MEDIA_KEY>"
  1. Upload the media file: Use the signed URL from the previous step to upload the media file. Make a PUT request to the URL with the selected media file as the request body and set the Content-Type header to the media file's MIME type.

    curl -X PUT -H "Content-Type: <FILE_MIME_TYPE>" -H 'Authorization: Bearer <JWT>' --upload-file <FILE_PATH> "<SIGNED_URL>"

    The request should return a 200 status code if the media file is uploaded successfully.

    Replace <SIGNED_URL> with the URL received in the previous step and <FILE_PATH> with the path to the media file on your system.

  2. Wait for media processing: After your media was upload, we need to perform a couple of validation in your files, the status of this validation will be indicated in the media status.

Poll the /media/<MEDIA_KEY> endpoint to check the media processing status. Keep polling until the response is 200 AND the status is PROCESSED.

curl -X GET "https://moments.poap.tech/media/<MEDIA_KEY>"

The response will contain the media's processing status:

  "status": "<PROCESSING_STATUS>"

If you receive an INVALID status, please check that the specified mime-type is correct.


⏱️ Wait for a reasonable amount of time (e.g., 2 seconds) between polling attempts. The process takes around 10s for 100MB media files.

  1. Create a Moment: Once the media is processed, create a Moment by making a POST request to the /moments endpoint with the required metadata.

The body for the request must comply with the following schema. The mediaKeys should contain the keys of the media you uploaded during the previous steps.

  "dropId": {
    "type": "integer",
  "tokenId": {
    "type": "integer",
  "author": {
    "type": "eth_wallet",
  "mediaKeys": {
    "type": "array",
    "items": {
      "type": "string",
      "format": "uuid"
  "description": {
    "type": "string",
    "maxLength": 600

The request you will need to make to our API has the following format.

curl -X POST -H "Content-Type: application/json" -H 'Authorization: Bearer <JWT>' -d '{
    "dropId": <DROP_ID>,
    "author": "<ETH_ACCOUNT>",
    "mediaKeys": <MEDIA_KEYS>,
    "description": "<DESCRIPTION>",
}' "https://moments.poap.tech/moments"

Remember to replace the placeholders (<SIGNED_URL>, <FILE_PATH>, <MEDIA_KEYS><DROP_ID>, and <ETH_ACCOUNT>) with the appropriate values before executing the curlcommands.
If the request is successful, the Moment will be created, and a success message can be displayed to the user. If there's an error, handle it accordingly and inform the user.

Retrieve Moments


The best way to retrieve Moments is by using our GraphQL API. You can explore it at the following URL: https://cloud.hasura.io/public/graphiql?endpoint=https://public.compass.poap.tech/v1/graphql.

Currently, this GraphQL API does not require an API Key. However, please be aware that changes may be implemented in the near future. Additionally, please note that Moments is continuously being developed, so you can expect changes in the schemas.

********Queries examples********

Get last 10 moments for the author 0x7CE5368171cC3D988157d7dab3D313d7bd43de3e:

query GetLastMomentsByAuthor($author: bpchar) {
    limit: 10
    where: {author: {_eq: $author}}
    order_by: {created_on: desc}
  ) {
    medias {
      gateways {

cURL request:

curl --location 'https://public.compass.poap.tech/v1/graphql' \
--header 'Content-Type: application/json' \
--data '{"query":"query GetLastMomentsByAuthor($author: bpchar) {\n  moments(\n    limit: 10\n    where: {author: {_eq: $author}}\n    order_by: {created_on: desc}\n  ) {\n    id\n    author\n    description\n    created_on\n    drop_id\n    medias {\n      mime_type\n      gateways {\n        type\n        url\n      }\n    }\n  }\n}\n","variables":{"author":"0x7ce5368171cc3d988157d7dab3d313d7bd43de3e"}}'