---
title: "Check what a forge supports"
description: "Ask a provider whether it supports an operation before you call it."
canonical_url: "https://forges.link/guides/capabilities"
---
# Check what a forge supports

> Ask a provider whether it supports an operation before you call it.

Forges don't all offer the same features, so before your code relies on an operation, it makes sense to ask the provider whether the forge has it. `provider.capabilities` holds the answer for every operation. The provider computes it up front without a network request, which means checking is free. If you want to know what the four possible values mean, [Capabilities](https://forges.link/concepts/capabilities) explains them.

## Call `can()` before an operation

The easiest way to check is `can()`, which takes a verb. A verb is the path of a method on the provider, such as `threads.addLabels` or `webhooks.create`. When support differs between kinds of threads, pass the kind as a second argument:

```ts
if (gh.can('threads.addLabels', thread.ref.kind)) {
  await gh.threads.addLabels(thread.ref, ['triage'])
}
```

`can()` answers `true` for every level of support that you can use, which includes `true`, `'experimental'`, `'emulated'` and `'unverified'`. If you want to treat any of these differently, call `support()` with the same verb. It returns the level itself:

```ts
if (provider.support('threads.addLabels', thread.ref.kind) === 'unverified') {
  console.warn('Adding labels has not been verified against this forge')
}
```

If you leave out the kind for a verb whose support differs by kind, you get the strongest level that any kind has. The `capabilities` object holds the same data, grouped the way the [capability matrix](https://forges.link/reference/capability-matrix) shows it.

## Provide a fallback

Every method exists on every provider, even if the forge can't do what it describes. Calling such a method doesn't fail at compile time. It rejects with `UnsupportedOperationError` at run time instead. That's why it's worth checking first, so you can decide what to do when an operation is missing:

```ts
if (provider.can('threads.upsertComment', thread.ref.kind)) {
  await provider.threads.upsertComment(thread.ref, {
    key: 'ci-report',
    body,
  })
}
else {
  await provider.threads.comment(thread.ref, body)
}
```

## Check what works without credentials

An anonymous provider reports only what the forge serves to anyone. To find out whether a read needs the user to sign in, ask an anonymous provider:

```ts
import { gitlab } from 'forges/gitlab'

const publicGitLab = gitlab({}).create()

publicGitLab.can('threads.get', 'issue') // true
publicGitLab.can('repos.labels') // false: GitLab shows labels to signed-in users only
```

## Check a stored capabilities object

Sometimes the provider isn't at hand. You might have saved its capabilities, or received them from another process. In that case, `supports(capabilities, verb, kind?)` and `supportOf(capabilities, verb, kind?)` give you the answers of `can()` and `support()` from a plain capabilities object:

```ts
import { supportOf, supports } from 'forges'

const canMerge = supports(saved, 'threads.merge')
const mergeLevel = supportOf(saved, 'threads.merge')
```

## Handle version-dependent capabilities

On some forges, what you can do depends on the version of the instance. GitHub Enterprise Server, for example, supports marking notifications as done from version 3.13 onwards. Because the provider computes its capabilities without a network request, it can't know the version by itself. If you know it, pass `instanceVersion` when you create the provider. Otherwise, call `refreshCapabilities()`. It reads the version once for each provider and updates `capabilities` accordingly:

```ts
const capabilities = await forge.refreshCapabilities()
```

## Find the scopes a verb needs

Capabilities describe what the forge supports, not what your credential is allowed to do. If `can()` returns `true` and a call still fails with `InsufficientScopeError`, the credential lacks a permission. [`scopesFor()`](https://forges.link/guides/authentication#show-the-scopes-an-operation-needs) tells you which one.


## Sitemap

See the full [sitemap](https://forges.link/sitemap.md) for all pages.
