> ## Documentation Index
> Fetch the complete documentation index at: https://yieldxyz.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Check RWA eligibility

> Decide whether a wallet can enter or exit a real-world-asset yield before you build the action.

Decide whether a specific wallet can enter, or exit, a specific real-world-asset (RWA) yield before you call `POST /v1/actions/enter` or `/exit`, so your UI shows the right state instead of relying on a failed action request. An RWA yield's eligibility rules are set by its issuer, per product, and are enforced at two independent layers: the caller's location and the wallet's own compliance status.

<Note>
  This guide covers deciding eligibility. To build and submit the enter or exit action once a wallet is eligible, see [Deposit and redeem RWAs](/guides/earn/rwas/deposit-redeem).
</Note>

## Prerequisites

* A yield.xyz API key, sent as `x-api-key` on every request.
* An RWA yield enabled for your project. See [Discover yields](/guides/earn/discover-yields).
* The wallet address you're checking eligibility for.

<Steps>
  <Step title="Discover the yield and read its requirements">
    Query `GET /v1/yields?types=real_world_asset` for the RWA yields enabled for your project, project-scoped like every yield endpoint, then read the yield's `mechanics.requirements` block:

    ```bash cURL theme={null}
    curl --request GET \
      --url https://api.yield.xyz/v1/yields/ethereum-usdc-nest-ntbill-vault \
      --header "x-api-key: $YIELD_API_KEY"
    ```

    ```json Response (excerpt) theme={null}
    {
      "id": "ethereum-usdc-nest-ntbill-vault",
      "status": { "enter": true, "exit": true },
      "mechanics": {
        "requirements": {
          "kycRequired": true,
          "kyc": {
            "kycMode": "external_redirect",
            "authorizeUrl": "https://app.nest.credit",
            "eligibility": {
              "defaultPolicy": "allow",
              "blockedCountries": ["US", "CU", "IR", "KP", "RU", "SY"],
              "usPersonAllowed": false,
              "geoBlockingEnforced": true,
              "investorEligibility": [],
              "subjectTypes": ["KYC", "KYB"]
            }
          }
        }
      }
    }
    ```

    `mechanics.requirements.kycRequired` tells you whether this product gates entry behind off-chain verification at all. When it's `true`, `mechanics.requirements.kyc` carries the rest: `kycMode` (how the issuer's flow is delivered), `authorizeUrl` (where to send the user), and `eligibility` (`defaultPolicy`, the country and subdivision lists, `usPersonAllowed`, `geoBlockingEnforced`, `investorEligibility` tiers, and accepted `subjectTypes`). See [KYC](/documentation/earn/rwas/kyc) for what every field in this block means; the blocked-country list above is Nest's own, not a fixed rule.
  </Step>

  <Step title="Check the wallet's KYC status">
    Call `GET /v1/yields/{yieldId}/kyc/status` with the wallet's `address` as a query parameter. It returns a status for every RWA yield, including ones that don't require KYC:

    ```bash cURL theme={null}
    curl --request GET \
      --url 'https://api.yield.xyz/v1/yields/ethereum-usdc-nest-ntbill-vault/kyc/status?address=0xYOUR_WALLET_ADDRESS' \
      --header "x-api-key: $YIELD_API_KEY"
    ```

    ```json Response (excerpt) theme={null}
    {
      "kycStatus": "not_started",
      "authorizeUrl": "https://app.nest.credit"
    }
    ```

    `kycStatus` is one of `not_required`, `not_started`, `pending`, `approved`, or `rejected`; see [KYC](/documentation/earn/rwas/kyc#checking-a-wallets-status) for what each one means. `pending` is declared but no current issuer returns it. `authorizeUrl` is optional: it is present only when the issuer provides an onboarding page, typically with `not_started` or `rejected`.
  </Step>

  <Step title="Route the wallet on the result">
    * `not_required` or `approved`: the wallet can proceed. Move on to [building the enter action](/guides/earn/rwas/deposit-redeem).
    * `not_started`: send the wallet to `authorizeUrl`, if present, to complete the issuer's onboarding, then poll this endpoint again before retrying the action. Treat `pending` the same way if you handle it, although no current issuer returns it.
    * `rejected`: the issuer has declined the wallet, or (for a yield with `kycRequired: false`) its module screened the address against an on-chain deny-list. Don't offer an enter or exit button. `authorizeUrl` is present for some issuers and absent for others, so check for it before linking.
  </Step>
</Steps>

## Distinguish a geo-block from a KYC rejection

Both failures reach you as an error on the action call itself, but they mean different things and carry different HTTP status codes:

| Cause | Enforced by | Response | What it means |
| - | - | - | - |
| Caller's IP is in a banned region (yield.xyz's mandatory list, your project's own list, or the yield's own `blockedCountries` when `geoBlockingEnforced` is `true`) | The geolocation guard on `enter`, `exit`, `manage`, and the `enter` and `exit` simulate routes | `403 Forbidden`, `{"message": "Access denied from <country>", "error": "Forbidden", "statusCode": 403}` | A location control, independent of wallet identity. See [Geo-blocking](/documentation/advanced-setup/geo-blocking/index) |
| Wallet isn't allowlisted by the issuer | A pre-flight compliance check some integrations run before building a transaction | `412 Precondition Failed`, error details carry `address`, `protocol` (the issuer's name), and `authorizeUrl` when the issuer has an onboarding flow | Investor eligibility, checked against the wallet, not the request's origin |

<Warning>
  If you call the Yield API from your own backend rather than directly from the end user's device, forward the end user's IP in `X-Forwarded-For`. Otherwise geo-blocking evaluates your server's location instead of theirs. See [Geo-blocking](/documentation/advanced-setup/geo-blocking/index#which-ip-is-checked).
</Warning>

Not every issuer's pre-flight rejection looks the same:

* Most KYC-gated issuers (Midas, Nest, Ondo, Securitize, Superstate) return a `412` whose details carry an `authorizeUrl`, so you can route the user straight to onboarding.
* Dinari's USD+ has `kycRequired: false`; there's no onboarding flow at all. Instead, yield.xyz checks the address against USD+'s on-chain deny-list before building a transaction, and a restricted address gets a `412` with `address` and `protocol` but no `authorizeUrl`. There's nowhere to send that wallet.
* Not every RWA module runs a pre-flight check at all. Where one doesn't, an ineligible wallet only finds out when the built transaction reverts on-chain, not from a `412` on the action request. Read `mechanics.requirements.kyc` before assuming an issuer's absence from this list means the yield is unconditionally open.

<Note>
  These two error shapes aren't a documented API contract you should pattern-match on: treat the HTTP status (`403` vs `412`) as the reliable signal, and use `/kyc/status` ahead of time so you show the right state instead of parsing a rejection.
</Note>

## A permissionless yield can still reject a wallet

`kycRequired: false` means there's no off-chain verification step, not that every wallet can transact. Midas sets `kycRequired: false` on mTBILL and mROX, but still checks every wallet against that product's on-chain greenlist (where the issuer has one enabled), blacklist, and sanctions list before building a transaction; a blocked wallet gets the same `412` shape as a KYC-gated Midas product, without a URL to send it to. Nest's own KYC metadata describes its flow as "permissionless for eligible users": there's no manual review queue, but every wallet is still screened on-chain by Plume's AML and Predicate policy before Nest builds a transaction. In both cases, the issuer's own metadata lists what's blocked, and that policy is set by the issuer, not by yield.xyz.

## Next steps

<Columns cols={2}>
  <Card title="Deposit and redeem RWAs" icon="landmark" href="/guides/earn/rwas/deposit-redeem">
    Build the enter action once the wallet is eligible, then track the position through exit.
  </Card>

  <Card title="KYC" icon="id-card" href="/documentation/earn/rwas/kyc">
    The full eligibility model: every field in the `kyc` metadata block and what it describes.
  </Card>

  <Card title="Geo-blocking" icon="globe" href="/documentation/advanced-setup/geo-blocking/index">
    Configure your project's own region restrictions on top of yield.xyz's mandatory list.
  </Card>

  <Card title="Issuers" icon="building-columns" href="/documentation/earn/rwas/coverage/issuers">
    Which issuers require KYC per product, and which don't.
  </Card>
</Columns>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.