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

# Frame Validation

> Validate incoming frame actions to get genuine data

Frames are mini-apps inside Farcaster casts. To read more about frames, check out the [Frames documentation](https://docs.farcaster.xyz/learn/what-is-farcaster/frames).

Frame actions are POST request sent to a Frame server, and is unauthenticated by default. Checking the POST request payload against the Hub is a necessary step to ensure the request is valid.

This guide demonstrates how to verify a frame action payload against the Hub with Neynar SDK.

Check out this [Getting started guide](/docs/getting-started-with-neynar) to learn how to set up your environment and get an API key.

First, initialize the client:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  import { NeynarAPIClient, Configuration } from "@neynar/nodejs-sdk";

  import { FeedType, FilterType } from "@neynar/nodejs-sdk/build/api/index.js";

  // make sure to set your NEYNAR_API_KEY .env
  // don't have an API key yet? get one at neynar.com
  const config = new Configuration({
    apiKey: process.env.NEYNAR_API_KEY,
  });
  const client = new NeynarAPIClient(config);
  ```
</CodeGroup>

Frame server hosts frames and handles Frame actions. Here's what POST request payload looks like for a Frame action:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  const payload = {
    untrustedData: {
      fid: 4286,
      url: "https://frame-server-example.com",
      messageHash: "0x8e95825cca8e81db6b9bd64bfdf626f7f172f02e",
      timestamp: 1707640145000,
      network: 1,
      buttonIndex: 1,
      castId: {
        fid: 4286,
        hash: "0x0000000000000000000000000000000000000001",
      },
    },
    trustedData: {
      messageBytes:
        "0a60080d10be2118d1bee82e20018201510a3268747470733a2f2f726e766d622d3130332d3132312d3133382d3131332e612e667265652e70696e6767792e6f6e6c696e6510011a1908be211214000000000000000000000000000000000000000112148e95825cca8e81db6b9bd64bfdf626f7f172f02e1801224096dd456e2752a358b33e19cfa833478974ce53379939e721e2875df14df4237a3ad3c9c9a27768ab59ea360df34893111c9aadc819a972d8ffd5f66976ffc00328013220836bf050647d18d304124823aaefa7c82eef99cbab2a120d8a8fe8e6d391929d",
    },
  };
  ```
</CodeGroup>

Anyone can spoof the request and send it to the Frame server. The check whether it's a valid request (ie. fid 4286 pressing buttonIndex 1 on a specific cast), we need to verify the request against the Hub.

<CodeGroup>
  ```javascript Javascript theme={"system"}
  const result = await client.validateFrameAction({
    messageBytesInHex: payload.trustedData.messageBytes,
  });
  console.log(result);
  ```
</CodeGroup>

<CodeGroup>
  ```json json theme={"system"}
  {
    "valid": true,
    "action": {
      "object": "validated_frame_action",
      "interactor": {
        "object": "user",
        "fid": 4286,
        "custody_address": "0x0076f74cc966fdd705ded40df8ab86604e4b5759",
        "username": "pixel",
        "display_name": "vincent",
        "pfp_url": "https://lh3.googleusercontent.com/WuVUEzf_r3qgz3cf4mtkXpLat5zNZbxKjoV-AldwfCQ8-_Y5yfWScMBEalpvbVgpt4ttXruxTD9GM983-UJBzMil5GRQF1qZ_aMY",
        "profile": {},
        "follower_count": 34997,
        "following_count": 905,
        "verifications": [
          "0x0076f74cc966fdd705ded40df8ab86604e4b5759",
          "0xb7254ce5cb61f69b3fc120b85f0f6b90d871036c"
        ],
        "verified_addresses": {
          "eth_addresses": [
          	"0x0076f74cc966fdd705ded40df8ab86604e4b5759",
  	        "0xb7254ce5cb61f69b3fc120b85f0f6b90d871036c"
          ],
        	"sol_addresses": [
            "7rhxnLV8C77o6d8oz26AgK8x8m5ePsdeRawjqvojbjnQ",
            "8g4Z9d6PqGkgH31tMW6FwxGhwYJrXpxZHQrkikpLJKrG"
          ],
        },
        "active_status": "active"
      },
      "tapped_button": {
        "index": 1
      },
      "input": {
        "text": ""
      },
      "url": "https://frame-server-example.com",
      "cast": {
        "object": "cast_dehydrated",
        "hash": "0x0000000000000000000000000000000000000001",
        "fid": 4286
      },
      "timestamp": "2024-02-11T08:29:05.000Z"
    },
    "signature_temporary_object": {
      "note": "temporary object for signature validation, might be removed in future versions. do not depend on this object, reach out if needed.",
      "hash": "0x8e95825cca8e81db6b9bd64bfdf626f7f172f02e",
      "hash_scheme": "HASH_SCHEME_BLAKE3",
      "signature": "lt1FbidSo1izPhnPqDNHiXTOUzeZOech4odd8U30I3o608nJondoq1nqNg3zSJMRHJqtyBmpctj/1fZpdv/AAw==",
      "signature_scheme": "SIGNATURE_SCHEME_ED25519",
      "signer": "0x836bf050647d18d304124823aaefa7c82eef99cbab2a120d8a8fe8e6d391929d"
    }
  }
  ```
</CodeGroup>

And that's it, a valid Frame action! You've successfully verified a frame action payload against the Hub with Neynar SDK. Note that frame payloads are only available in responses, not in initial requests. Attempts to fetch a payload during a request will result in an error. If you want to fetch cast while doing frame validation, refer to our [How to get cast information from URL](/docs/how-to-get-cast-information-from-url) guide.

<Info>
  ### Ready to start building?

  Get your subscription at [neynar.com](https://neynar.com) and reach out to us on [Slack](https://neynar.com/slack) with any questions!
</Info>
