openapi: 3.1.0 info: title: ROB Domains Agent API description: | ROB Domains is a Web3 domain name system built on the Robinhood Chain (Chain ID 4663). This API enables AI agents to search domains, read profiles, and generate unsigned transaction payloads for minting, setting a primary domain, and updating profiles. ## Key Design Principles - **Read-only by default** — GET endpoints query on-chain state directly. No auth required. - **Transaction payloads, not execution** — POST endpoints return ABI-encoded transaction data that the user's wallet signs and broadcasts. The API never holds private keys. - **No API keys** — Public read access. Wallet signatures authorize on-chain writes. - **Additive workflow** — Use `POST /agent/workflow/register-domain` to get a complete multi-step execution plan in one call. ## Transaction Flow 1. Call a `POST /agent/tx/*` endpoint with your parameters. 2. Receive a `TransactionPayload` with `to`, `data`, `value`, `chainId`. 3. Pass the payload to the user's wallet (MetaMask, WalletConnect, etc.). 4. The wallet signs and broadcasts the transaction. 5. Confirm on-chain via the Robinhood Chain explorer. version: 1.0.0 contact: name: ROB Domains url: https://robdn.com license: name: MIT servers: - url: https://robdn.com description: Production tags: - name: Status description: Platform status and contract addresses - name: Read description: On-chain domain and profile lookups - name: Transactions description: Unsigned transaction payload generation - name: Workflows description: Multi-step execution plans paths: /agent/status: get: operationId: getAgentStatus summary: Platform status description: Returns platform status, chain info, contract addresses, and available endpoints. tags: [Status] responses: '200': description: Platform is operational content: application/json: schema: $ref: '#/components/schemas/SuccessResponse_AgentStatus' example: success: true data: status: operational version: '1.0.0' chain: name: Robinhood chainId: 4663 rpcUrl: https://rpc.mainnet.chain.robinhood.com explorerUrl: https://robinhoodchain.blockscout.com symbol: ETH contracts: domainNFT: '0x37F7ba486afE8Be3C3C70A4FC3eCacC6DD51c6C8' marketplace: '0xAefec6e65ADE8D95c0Cf69D20e9254556f6cC637' resolver: '0xeDe40500f6047F2Ef8d8F5dec12F096969A1bF47' endpoints: - 'GET /agent/status' - 'GET /agent/search/{domain}' - 'GET /agent/profile/{domain}' - 'GET /agent/reverse/{wallet}' - 'GET /agent/primary/{wallet}' - 'POST /agent/tx/mint' - 'POST /agent/tx/set-primary' - 'POST /agent/tx/update-profile' - 'POST /agent/workflow/register-domain' auth: No API keys required. Wallet signatures authorize on-chain writes. docs: https://robdn.com/developer openapi: https://robdn.com/agent/docs/openapi.yaml manifest: https://robdn.com/.well-known/ai-plugin.json meta: chain: Robinhood chainId: 4663 timestamp: '2024-01-01T00:00:00.000Z' /agent/search/{domain}: get: operationId: searchDomain summary: Search for a domain description: | Search for a .rob domain by name. Returns availability status, current owner, token ID, primary owner, and profile summary if the domain is already minted. Accepts the domain with or without the ".rob" suffix. tags: [Read] parameters: - name: domain in: path required: true schema: type: string description: Domain name with or without ".rob" suffix (e.g. "alice" or "alice.rob") example: alice responses: '200': description: Domain search result content: application/json: schema: $ref: '#/components/schemas/SuccessResponse_DomainSearch' examples: available: summary: Domain is available value: success: true data: domain: alice fullDomain: alice.rob available: true owner: null tokenId: null primaryOwner: null profile: null meta: chain: Robinhood chainId: 4663 timestamp: '2024-01-01T00:00:00.000Z' taken: summary: Domain is taken value: success: true data: domain: alice fullDomain: alice.rob available: false owner: '0xAbCd1234...' tokenId: '42' primaryOwner: '0xAbCd1234...' profile: bio: Web3 builder profilePicture: https://example.com/pic.jpg coverImage: '' background: bg-gradient-to-br from-purple-900 to-indigo-900 socialLinks: - platform: twitter url: https://twitter.com/alice icon: twitter customLinks: [] meta: chain: Robinhood chainId: 4663 timestamp: '2024-01-01T00:00:00.000Z' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalError' /agent/profile/{domain}: get: operationId: getProfile summary: Get domain profile description: | Returns the full on-chain profile for a .rob domain, including bio, social links, custom links, profile picture, cover image, and background. tags: [Read] parameters: - name: domain in: path required: true schema: type: string description: Domain name with or without ".rob" suffix example: alice responses: '200': description: Full domain profile content: application/json: schema: $ref: '#/components/schemas/SuccessResponse_Profile' example: success: true data: domain: alice fullDomain: alice.rob owner: '0xAbCd1234...' tokenId: '42' profile: bio: Web3 builder and open source contributor profilePicture: https://example.com/pic.jpg coverImage: https://example.com/cover.jpg background: bg-gradient-to-br from-purple-900 to-indigo-900 socialLinks: - platform: twitter url: https://twitter.com/alice icon: twitter - platform: github url: https://github.com/alice icon: github customLinks: - title: My Website url: https://alice.com meta: chain: Robinhood chainId: 4663 timestamp: '2024-01-01T00:00:00.000Z' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' /agent/reverse/{wallet}: get: operationId: reverseResolve summary: Reverse resolve wallet to domain description: | Reverse-resolves an Ethereum wallet address to its primary .rob domain as registered in the on-chain RobResolver contract. Returns an empty result (not an error) when no primary domain is set. tags: [Read] parameters: - name: wallet in: path required: true schema: type: string pattern: '^0x[0-9a-fA-F]{40}$' description: Ethereum wallet address (0x-prefixed) example: '0xAbCd1234567890AbCd1234567890AbCd12345678' responses: '200': description: Reverse resolution result content: application/json: schema: $ref: '#/components/schemas/SuccessResponse_Reverse' examples: resolved: summary: Primary domain found value: success: true data: wallet: '0xAbCd1234...' tokenId: '42' domainName: alice fullDomain: alice.rob resolved: true meta: chain: Robinhood chainId: 4663 timestamp: '2024-01-01T00:00:00.000Z' not_set: summary: No primary domain set value: success: true data: wallet: '0xAbCd1234...' tokenId: '0' domainName: '' fullDomain: '' resolved: false meta: chain: Robinhood chainId: 4663 timestamp: '2024-01-01T00:00:00.000Z' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalError' /agent/primary/{wallet}: get: operationId: getPrimaryDomain summary: Get primary domain for wallet description: | Returns the primary .rob domain set for a wallet via the on-chain RobResolver. Includes the resolution source for transparency. tags: [Read] parameters: - name: wallet in: path required: true schema: type: string pattern: '^0x[0-9a-fA-F]{40}$' description: Ethereum wallet address (0x-prefixed) example: '0xAbCd1234567890AbCd1234567890AbCd12345678' responses: '200': description: Primary domain result content: application/json: schema: $ref: '#/components/schemas/SuccessResponse_Primary' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalError' /agent/tx/mint: post: operationId: buildMintTransaction summary: Build mint transaction description: | Generates an unsigned transaction payload for minting a .rob domain NFT. The domain availability is verified before returning the payload. **The API does NOT execute the transaction.** Pass the returned payload to the user's wallet for signing and broadcasting. tags: [Transactions] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MintRequest' example: domain: alice responses: '200': description: Unsigned mint transaction payload content: application/json: schema: $ref: '#/components/schemas/SuccessResponse_Transaction' example: success: true data: to: '0x37F7ba486afE8Be3C3C70A4FC3eCacC6DD51c6C8' data: '0x...' value: '0' chainId: 4663 contractName: DomainNFT method: mintDomain description: Mint the domain "alice.rob" as an NFT on Robinhood Chain. meta: chain: Robinhood chainId: 4663 timestamp: '2024-01-01T00:00:00.000Z' '400': $ref: '#/components/responses/BadRequest' '409': $ref: '#/components/responses/Conflict' '500': $ref: '#/components/responses/InternalError' /agent/tx/set-primary: post: operationId: buildSetPrimaryTransaction summary: Build set-primary transaction description: | Generates an unsigned transaction payload for setting a .rob domain token as the caller's primary domain in the RobResolver contract. Verifies token ownership before returning the payload. **The API does NOT execute the transaction.** tags: [Transactions] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SetPrimaryRequest' example: tokenId: '42' wallet: '0xAbCd1234567890AbCd1234567890AbCd12345678' responses: '200': description: Unsigned set-primary transaction payload content: application/json: schema: $ref: '#/components/schemas/SuccessResponse_Transaction' '400': $ref: '#/components/responses/BadRequest' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' /agent/tx/update-profile: post: operationId: buildUpdateProfileTransaction summary: Build update-profile transaction(s) description: | Generates one or more unsigned transaction payloads for updating a .rob domain profile. When `socialLinks` or `customLinks` are provided, multiple payloads are returned. **Sign and send them in order.** **The API does NOT execute any transaction.** tags: [Transactions] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateProfileRequest' example: tokenId: '42' bio: Web3 builder profilePicture: https://example.com/pic.jpg coverImage: '' background: bg-gradient-to-br from-purple-900 to-indigo-900 socialLinks: - platform: twitter url: https://twitter.com/alice customLinks: - title: My Website url: https://alice.com responses: '200': description: Unsigned update-profile transaction payload(s) content: application/json: schema: $ref: '#/components/schemas/SuccessResponse_UpdateProfile' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' /agent/workflow/register-domain: post: operationId: registerDomainWorkflow summary: Full domain registration plan description: | Returns a complete multi-step execution plan for registering a .rob domain. All transaction payloads are included — the wallet signs and sends each step in order. Steps produced: 1. **Mint Domain** — always present 2. **Set Primary** — present when `setPrimary: true` 3. **Update Profile** — present when profile fields are provided **The API does NOT execute anything. This is a planning endpoint only.** tags: [Workflows] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RegisterDomainRequest' examples: mint_only: summary: Mint only value: domain: alice wallet: '0xAbCd1234567890AbCd1234567890AbCd12345678' full_registration: summary: Full registration with profile value: domain: alice wallet: '0xAbCd1234567890AbCd1234567890AbCd12345678' setPrimary: true profile: bio: Web3 builder profilePicture: https://example.com/pic.jpg socialLinks: - platform: twitter url: https://twitter.com/alice responses: '200': description: Execution plan with all transaction payloads content: application/json: schema: $ref: '#/components/schemas/SuccessResponse_ExecutionPlan' '400': $ref: '#/components/responses/BadRequest' '409': $ref: '#/components/responses/Conflict' '500': $ref: '#/components/responses/InternalError' components: schemas: TransactionPayload: type: object required: [to, data, value, chainId, contractName, method, description] properties: to: type: string description: Contract address to send the transaction to example: '0x37F7ba486afE8Be3C3C70A4FC3eCacC6DD51c6C8' data: type: string description: ABI-encoded calldata example: '0x...' value: type: string description: Native ETH value in wei (decimal string). "0" for non-payable. example: '0' chainId: type: integer description: EIP-155 chain ID example: 4663 contractName: type: string description: Human-readable contract name example: DomainNFT method: type: string description: Solidity function name example: mintDomain description: type: string description: Human-readable description of what this transaction does SocialLink: type: object required: [platform, url] properties: platform: type: string enum: [ twitter, instagram, github, linkedin, youtube, facebook, twitch, discord, telegram, tiktok, ] url: type: string format: uri icon: type: string default: '' CustomLink: type: object required: [title, url] properties: title: type: string maxLength: 100 url: type: string format: uri ProfileSummary: type: object properties: bio: type: string profilePicture: type: string coverImage: type: string background: type: string socialLinks: type: array items: $ref: '#/components/schemas/SocialLink' customLinks: type: array items: $ref: '#/components/schemas/CustomLink' MintRequest: type: object required: [domain] properties: domain: type: string minLength: 1 maxLength: 63 pattern: '^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$' description: Domain label without ".rob" suffix example: alice SetPrimaryRequest: type: object required: [tokenId, wallet] properties: tokenId: type: string pattern: '^\d+$' description: On-chain token ID of the domain example: '42' wallet: type: string pattern: '^0x[0-9a-fA-F]{40}$' description: Wallet address that owns the token example: '0xAbCd1234567890AbCd1234567890AbCd12345678' UpdateProfileRequest: type: object required: [tokenId] properties: tokenId: type: string pattern: '^\d+$' description: On-chain token ID of the domain to update example: '42' profilePicture: type: string description: URL of profile picture (empty string to clear) default: '' coverImage: type: string description: URL of cover image (empty string to clear) default: '' bio: type: string maxLength: 500 default: '' background: type: string maxLength: 200 description: Tailwind CSS background class string default: '' socialLinks: type: array items: $ref: '#/components/schemas/SocialLink' maxItems: 10 default: [] customLinks: type: array items: $ref: '#/components/schemas/CustomLink' maxItems: 20 default: [] RegisterDomainRequest: type: object required: [domain, wallet] properties: domain: type: string minLength: 1 maxLength: 63 pattern: '^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$' example: alice wallet: type: string pattern: '^0x[0-9a-fA-F]{40}$' example: '0xAbCd1234567890AbCd1234567890AbCd12345678' setPrimary: type: boolean default: false description: Include a Set Primary Domain step in the plan profile: type: object description: Optional profile to set after minting properties: bio: type: string maxLength: 500 profilePicture: type: string coverImage: type: string background: type: string socialLinks: type: array items: $ref: '#/components/schemas/SocialLink' customLinks: type: array items: $ref: '#/components/schemas/CustomLink' WorkflowStep: type: object properties: step: type: integer action: type: string description: type: string transaction: oneOf: - $ref: '#/components/schemas/TransactionPayload' - type: array items: $ref: '#/components/schemas/TransactionPayload' ResponseMeta: type: object properties: chain: type: string example: Robinhood chainId: type: integer example: 4663 timestamp: type: string format: date-time ErrorResponse: type: object required: [success, code, message] properties: success: type: boolean enum: [false] code: type: integer example: 400 message: type: string details: type: string SuccessResponse_AgentStatus: type: object properties: success: type: boolean enum: [true] data: type: object meta: $ref: '#/components/schemas/ResponseMeta' SuccessResponse_DomainSearch: type: object properties: success: type: boolean enum: [true] data: type: object properties: domain: type: string fullDomain: type: string available: type: boolean owner: type: string nullable: true tokenId: type: string nullable: true primaryOwner: type: string nullable: true profile: nullable: true $ref: '#/components/schemas/ProfileSummary' meta: $ref: '#/components/schemas/ResponseMeta' SuccessResponse_Profile: type: object properties: success: type: boolean enum: [true] data: type: object properties: domain: type: string fullDomain: type: string owner: type: string tokenId: type: string profile: $ref: '#/components/schemas/ProfileSummary' meta: $ref: '#/components/schemas/ResponseMeta' SuccessResponse_Reverse: type: object properties: success: type: boolean enum: [true] data: type: object properties: wallet: type: string tokenId: type: string domainName: type: string fullDomain: type: string resolved: type: boolean meta: $ref: '#/components/schemas/ResponseMeta' SuccessResponse_Primary: type: object properties: success: type: boolean enum: [true] data: type: object properties: wallet: type: string tokenId: type: string domainName: type: string fullDomain: type: string resolved: type: boolean source: type: string meta: $ref: '#/components/schemas/ResponseMeta' SuccessResponse_Transaction: type: object properties: success: type: boolean enum: [true] data: $ref: '#/components/schemas/TransactionPayload' meta: $ref: '#/components/schemas/ResponseMeta' SuccessResponse_UpdateProfile: type: object properties: success: type: boolean enum: [true] data: type: object properties: tokenId: type: string transactionCount: type: integer note: type: string nullable: true transactions: type: array items: $ref: '#/components/schemas/TransactionPayload' meta: $ref: '#/components/schemas/ResponseMeta' SuccessResponse_ExecutionPlan: type: object properties: success: type: boolean enum: [true] data: type: object properties: domain: type: string fullDomain: type: string wallet: type: string totalSteps: type: integer steps: type: array items: $ref: '#/components/schemas/WorkflowStep' warning: type: string meta: $ref: '#/components/schemas/ResponseMeta' responses: BadRequest: description: Bad request — validation error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false code: 400 message: Domain is required details: 'Field: domain' NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false code: 404 message: Domain not found or not yet minted Forbidden: description: Wallet does not own the token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false code: 403 message: Wallet 0x... does not own token #42 Conflict: description: Domain already taken content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false code: 409 message: Domain "alice.rob" is already taken InternalError: description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false code: 500 message: Domain search failed — please try again