# Token-gating using badges

Token gating by Badge spec implies that only holders of Badges belonging to one or more specs are able to get through the token gate.

## Finding the badge spec id

First, you need to get the id of the Badge Spec that you used to issue badges to different addresses.

You can find the Badge spec id in the url of the Badge page.

```json
https://beta.otterspace.xyz/badges/bafyreifcjs56sk5gseb75e45rjebh4kwln3trwi6aphhacf727lkshq74e 
```

## Fetching all the holders of a badge spec <a href="#block-dfc5e417412245708e1cb8c33c14d822" id="block-dfc5e417412245708e1cb8c33c14d822"></a>

You can use our [subgraph](https://thegraph.com/hosted-service/subgraph/otterspace-xyz/badges-optimism) to fetch all the badge owners of that spec

```graphql
{
  badgeSpec(id: "bafyreicl3unvw6tvzjfduvrhxbfi74gsob6mpf6ekn3s2nkopqz2phtx7e") {
    id
    metadata {
      name
      description
      image
      expiresAt
    }
    totalBadgesCount
    badges {
      id
      owner
      createdAt
    }
  }
}
```

## Does an address hold a Badge belonging to this spec? <a href="#block-af7faa94cb834da3afcea2d6599fc198" id="block-af7faa94cb834da3afcea2d6599fc198"></a>

If you already know the address of a user, you can simply check if this address owns a badge with the spec that you intend to gate. For example, see the query below. Here we’re checking if the address `0x77B476429826C5ba77885D08F272d89D8F1Ed0e4` owns a **Pioneer badge** issued by the **Otterspace** Raft.&#x20;

```graphql
{
  badges(where: {owner: "0x77B476429826C5ba77885D08F272d89D8F1Ed0e4", spec: "bafyreicl3unvw6tvzjfduvrhxbfi74gsob6mpf6ekn3s2nkopqz2phtx7e"}) {
    id
    createdAt
    owner
    createdAt
    spec {
      id
      metadata {
        name
      }
      raft {
        id
        metadata {
          name
        }
      }
    }
  }
}
```

And if you’d like to check if an address owns one of the badges, simply use `spec_in` filter

```graphql
{
  badges(
    where: {owner: "0x77B476429826C5ba77885D08F272d89D8F1Ed0e4", spec_in: ["bafyreicl3unvw6tvzjfduvrhxbfi74gsob6mpf6ekn3s2nkopqz2phtx7e","bafyreia2lnu2jmr6sqqijzd3xt6fw2qriyy2vbq57zikzrkeyxfvlpqp3i"]}
  ) {
    id
    createdAt
    owner
    createdAt
    spec {
      id
      metadata {
				name
			}
      raft {
        id
        metadata {
					name 
				}
      }
    }
  }
}
```

## Filtering out expired and revoked Badges <a href="#block-f21deb7ed2d247ceab04e0b51a74151d" id="block-f21deb7ed2d247ceab04e0b51a74151d"></a>

One thing that makes Badges different from other NFTs is that they can expire. Expired Badges shouldn’t be able to be used to access spaces and resources. You can check if a Badge is expired by looking at the expiry date in the metadata.

## Filtering by community <a href="#block-83f3750341364940a1f101cea52ef4e4" id="block-83f3750341364940a1f101cea52ef4e4"></a>

If you are building a token-gating UI, you probably want to allow an account admin to select from the Badge Specs belonging to that account.

The unique identifier of a Raft is the Token Id of an ERC721 token which is airdropped to the community during its formation. The Raft Id can be found in the community’s profile url.

```json
https://beta.otterspace.xyz/communities/1
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.otterspace.xyz/guides/token-gating-using-badges.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
