Quiltt Logo

Custom Metadata

Core resources in Quiltt can be easily extended with additional custom information, using the metadata field.

Link to this section#Use Cases

The metadata field allows you to store arbitrary custom data in a structured manner. You can use this to store many types of static or dynamic information that may be useful to retrieve later. Below are some examples:

Link to this section#Persist Static Data

  • An internal ID or reference, such as the ID of the resource in your database
  • An external identifier for a 3rd party system, like authentication or analytics
  • A Profile's nickname or preferred pronoun

Link to this section#Track Dynamic States

  • When was the last time someone interacted with a Connection or Account in your app?
  • Is an Account treated as "active" in your system?
  • Should a Transaction be hidden in your UI?

Link to this section#Supported Resources

The following resources currently expose a metadata field via corresponding GraphQL mutations:

ResourceGraphQL Mutation
ProfileprofileUpdate
ConnectionconnectionUpdate
AccountaccountUpdate
TransactiontransactionUpdate

Additionally, Profile metadata can also be managed using the below server-to-server endpoints:

POSThttps://auth.quiltt.io/v1/users/session
POSThttps://auth.quiltt.io/v1/profiles
PATCHhttps://auth.quiltt.io/v1/profiles/{profileId}

Link to this section#Usage Examples

The best way to interact with metadata is by using the GraphQL explorer in the Quiltt Dashboard, or Quiltt Hub.

For this example, we'll assume we have a Profile named Quiltty, then add and remove some metadata.

Link to this section#Adding Metadata

First we'll assign some internal identifiers to track via metadata.

Link to this section#Request

mutation {
  profileUpdate(
    input: {
      metadata: {
        internal_user_id: 12345,
        firebase_id: "Xk3D12aB4zO7QW5z8s9Y"
      }
    }
  ) {
    record {
      id
      metadata
    }
  }
}

Link to this section#Response

{
  "data": {
    "profileUpdate": {
      "record": {
        "id": "p_12vTuTMBAXZQM6zb7mjRml",
        "metadata": {
          "internal_user_id": 12345,
          "firebase_id": "Xk3D12aB4zO7QW5z8s9Y"
        }
      }
    }
  }
}

Link to this section#Changing Metadata

Let's say we've learned that Quiltty's favorite color is purple. We can reflect that on the Profile by adding that data to metadata:

Link to this section#Request

mutation {
  profileUpdate(input: {metadata: {favoriteColor: "purple"}}) {
    record {
      id
      metadata
    }
  }
}

Link to this section#Response

{
  "data": {
    "profileUpdate": {
      "record": {
        "id": "p_12vTuTMBAXZQM6zb7mjRml",
        "metadata": {
          "internal_user_id": 12345,
          "firebase_id": "Xk3D12aB4zO7QW5z8s9Y",
          "favoriteColor": "purple"
        }
      }
    }
  }
}

Note that the existing metadata keys are not touched unless they're explicitly set in the request.

Now let's say we've migrated off of Firebase. To delete the metadata entry, we can simply set the key to null:

Link to this section#Request

mutation {
  profileUpdate(input: {metadata: {favoriteColor: null}}) {
    record {
      id
      metadata
    }
  }
}

Link to this section#Response

{
  "data": {
    "profileUpdate": {
      "record": {
        "id": "p_12vTuTMBAXZQM6zb7mjRml",
        "metadata": {
          "firebase_id": "Xk3D12aB4zO7QW5z8s9Y"
        }
      }
    }
  }
}

To clear metadata entirely, we can set all the defined keys to null or the entire metadata object to null.

Link to this section#Request

mutation {
  profileUpdate(input: {metadata: null}) {
    record {
      id
      metadata
    }
  }
}

Link to this section#Response

{
  "data": {
    "profileUpdate": {
      "record": {
        "id": "p_12vTuTMBAXZQM6zb7mjRml",
        "metadata": null
      }
    }
  }
}

Link to this section#Filtering by Metadata

In GraphQL, you can filter records by the contents of the metadata field.

For example, here's how you can query Connections by an internal identifier you've written to a Connection's metadata.

Link to this section#Request

query FilterConnectionsByMetadata {
  connections(filter: { metadata: { internal_connection_id: "my_custom_id" } }) {
    id
    metadata
  }
}

Link to this section#Response

{
  "data": {
    "connections": [
      {
        "id": "conn_12tgD1WgzFgsy9fqKpW9b3",
        "metadata": {
          "internal_connection_id": "my_custom_id"
        }
      }
    ]
  }
}

Link to this section#Limitations

Custom metadata must be sent as a valid key-value JSON object, and must include at least 1 string key. There is a maximum capacity of 50 keys per record, with key names limited to 50 characters and values limited to 500 characters.

You should avoid storing any sensitive data that may contain PII (Personally Identifiable Information) in the metadata object. If you need to store sensitive data like emails, phone numbers or birthdays, use the dedicated fields on the Profile, which provide an additional level of encryption, as explained in the Core Concepts guide.