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

# Initiate an intent with Permit2

> Funds a quote gaslessly with a signed Permit2 PermitSingle. Requires an API key.

Funds a quote gaslessly with a signed Permit2 `PermitSingle` (AllowanceTransfer, not SignatureTransfer). `chainId` is the chain the permit was signed for, `target.quoteId` names the quote, `permit2.spender` is the quote's `execution.vault`, and `signature` is the top-level EIP-712 signature. `permit2.sigDeadline` is a decimal string. The first submission answers `202` with a gasless job; resending the same signature returns the existing job with `200`.

Requires `x-api-key`. Partner pricing, attribution, and enabled features are tied to the key. Without a key the gateway answers `403` with a plain JSON body (`{"Message": "User is not authorized ..."}`); a key that is unknown, revoked, or not enabled for v1 answers `401 invalid-api-key`. No requests-per-second quota is published. Handle `429` and honor `Retry-After` when present.

Examples use real mainnet token and contract addresses with placeholder wallets, hashes, signatures, and IDs.


## OpenAPI

````yaml api-v1.openapi.json POST /v1/intents/submit/permit2
openapi: 3.1.0
info:
  title: Eco API
  version: v1
  description: >-
    Reference for the Eco API at https://api.eco.com/v1: quotes, chain and token
    discovery, gasless funding, intent status, and Circle Gateway fast deposits.
    Every operation requires an API key except the Circle Gateway operations,
    which are open.
servers:
  - url: https://api.eco.com
    description: Eco API
security: []
tags:
  - name: quotes
  - name: intents
  - name: status
  - name: discovery
  - name: circle-gateway
paths:
  /v1/intents/submit/permit2:
    post:
      tags:
        - intents
      summary: Initiate an intent with Permit2
      description: >-
        Funds a quote gaslessly with a signed Permit2 `PermitSingle`
        (AllowanceTransfer, not SignatureTransfer). `chainId` is the chain the
        permit was signed for, `target.quoteId` names the quote,
        `permit2.spender` is the quote's `execution.vault`, and `signature` is
        the top-level EIP-712 signature. `permit2.sigDeadline` is a decimal
        string. The first submission answers `202` with a gasless job; resending
        the same signature returns the existing job with `200`.


        Requires `x-api-key`. Partner pricing, attribution, and enabled features
        are tied to the key. Without a key the gateway answers `403` with a
        plain JSON body (`{"Message": "User is not authorized ..."}`); a key
        that is unknown, revoked, or not enabled for v1 answers `401
        invalid-api-key`.


        No requests-per-second quota is published. Handle `429` and honor
        `Retry-After` when present.


        Examples use real mainnet token and contract addresses with placeholder
        wallets, hashes, signatures, and IDs.
      operationId: intents.submit.permit2
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                chainId:
                  type: integer
                  exclusiveMinimum: 0
                target:
                  type: object
                  properties:
                    quoteId:
                      type: string
                  required:
                    - quoteId
                  additionalProperties: false
                permit2:
                  type: object
                  properties:
                    details:
                      type: object
                      properties:
                        token:
                          type: string
                        amount:
                          type: string
                          maxLength: 78
                        expiration:
                          type: integer
                          minimum: 0
                          maximum: 281474976710655
                          description: Permit2 allowance expiration (uint48, Unix seconds)
                        nonce:
                          type: integer
                          minimum: 0
                          maximum: 281474976710655
                      required:
                        - token
                        - amount
                        - expiration
                        - nonce
                    spender:
                      type: string
                      description: >-
                        The Permit2 spender — on a quote target, the quote's
                        execution.vault
                    sigDeadline:
                      type: string
                      maxLength: 78
                      description: >-
                        Signature deadline (uint256 Unix seconds, decimal
                        string; max-uint = no expiry)
                  required:
                    - details
                    - spender
                    - sigDeadline
                signature:
                  type: string
                  minLength: 130
                  maxLength: 132
              required:
                - chainId
                - target
                - permit2
                - signature
            examples:
              quote-target:
                summary: >-
                  Fund the exact-in quote above with Permit2; spender is the
                  quote's execution.vault (placeholder signature)
                value:
                  chainId: 8453
                  target:
                    quoteId: quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23
                  permit2:
                    details:
                      token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
                      amount: '1000000'
                      expiration: 1789526504
                      nonce: 0
                    spender: '0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F'
                    sigDeadline: '1789526504'
                  signature: >-
                    0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b
      responses:
        '200':
          description: Existing job for the same signature and target.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  status:
                    type: string
                    enum:
                      - pending
                      - processing
                      - published
                      - partial
                      - failed
                      - unknown
                  signatureHash:
                    type: string
                  subStatuses:
                    type: array
                    items:
                      type: object
                      properties:
                        chainId:
                          type: integer
                        quoteIds:
                          type: array
                          items:
                            type: string
                        txHash:
                          type:
                            - string
                            - 'null'
                        intentHashes:
                          type: array
                          items:
                            type: string
                        state:
                          type: string
                          enum:
                            - pending
                            - submitted
                            - published
                            - failed
                      required:
                        - chainId
                        - quoteIds
                        - txHash
                        - intentHashes
                        - state
                  createdAt:
                    type: integer
                  updatedAt:
                    type: integer
                required:
                  - id
                  - status
                  - signatureHash
                  - subStatuses
                  - createdAt
                  - updatedAt
              examples:
                job:
                  summary: 'Same signature resent: the existing job'
                  value:
                    id: gasless:0f450218-1b2c-4d3e-8f9a-0b1c2d3e4f5a
                    status: published
                    signatureHash: >-
                      0x94245dddfb2339e6e06fe251c90de895bf2995ff3c5a5fb185390f1850ed6726
                    subStatuses:
                      - chainId: 8453
                        quoteIds:
                          - quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23
                        txHash: >-
                          0x3ef97346fd076aadb54c851f33ba9234feb34d27442b9bb0abc7a0d75827af13
                        intentHashes:
                          - >-
                            0x3f1886e7c3a4cab62b4a0661e393600f0917d5a514652e96623b0f17ce0d3749
                        state: published
                    createdAt: 1789522604
                    updatedAt: 1789522654
        '202':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  status:
                    type: string
                    enum:
                      - pending
                      - processing
                      - published
                      - partial
                      - failed
                      - unknown
                  signatureHash:
                    type: string
                  subStatuses:
                    type: array
                    items:
                      type: object
                      properties:
                        chainId:
                          type: integer
                        quoteIds:
                          type: array
                          items:
                            type: string
                        txHash:
                          type:
                            - string
                            - 'null'
                        intentHashes:
                          type: array
                          items:
                            type: string
                        state:
                          type: string
                          enum:
                            - pending
                            - submitted
                            - published
                            - failed
                      required:
                        - chainId
                        - quoteIds
                        - txHash
                        - intentHashes
                        - state
                  createdAt:
                    type: integer
                  updatedAt:
                    type: integer
                required:
                  - id
                  - status
                  - signatureHash
                  - subStatuses
                  - createdAt
                  - updatedAt
              examples:
                job:
                  summary: New gasless job accepted
                  value:
                    id: gasless:0f450218-1b2c-4d3e-8f9a-0b1c2d3e4f5a
                    status: processing
                    signatureHash: >-
                      0x94245dddfb2339e6e06fe251c90de895bf2995ff3c5a5fb185390f1850ed6726
                    subStatuses:
                      - chainId: 8453
                        quoteIds:
                          - quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23
                        txHash: null
                        intentHashes: []
                        state: pending
                    createdAt: 1789522604
                    updatedAt: 1789522614
        '400':
          description: Request failed validation
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.eco.com/v1/errors/invalid-request
                title: Request failed validation
                status: 400
                code: invalid-request
                detail: >-
                  chainId: Invalid input: expected number, received undefined;
                  permit2.sigDeadline: Invalid input: expected string, received
                  number
                errors:
                  - field: chainId
                    detail: 'Invalid input: expected number, received undefined'
                  - field: permit2.sigDeadline
                    detail: 'Invalid input: expected string, received number'
                requestId: f371e43e6fd4406b10e19487b3170edf
        '401':
          description: >-
            From the gateway (application/json), without `detail`: the key is
            unknown, revoked, or not enabled for v1. From the API
            (application/problem+json): `invalid-api-key` with `detail: "The
            request could not be attributed to an authorized API key."` means
            the key is enabled for v1 but not yet mapped to a partner (contact
            Eco); `invalid-signature` means the signature does not recover to
            the expected signer; `authorization-expired` means its validity
            window has passed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.eco.com/v1/errors/invalid-api-key
                title: API key is missing, unknown, or revoked
                status: 401
                code: invalid-api-key
                requestId: 98e4c42f-9c70-4539-843e-8d31803001e6
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                unmapped:
                  summary: 'Live: key valid for v1 but not mapped to a partner'
                  value:
                    type: https://api.eco.com/v1/errors/invalid-api-key
                    title: API key is missing, unknown, or revoked
                    status: 401
                    code: invalid-api-key
                    requestId: f81fb73d-0fd2-4cdc-a14d-882797bb89a7
                    detail: >-
                      The request could not be attributed to an authorized API
                      key.
                invalid-signature:
                  summary: 'Live: signature does not verify'
                  value:
                    type: https://api.eco.com/v1/errors/invalid-signature
                    title: Signature verification failed
                    status: 401
                    code: invalid-signature
                    requestId: 4ece761247bfc14267057f95ee3071bc
                    legacyCode: eco-quotes:1003
        '403':
          description: >-
            No API key supplied. The gateway rejects the request before it
            reaches the API, with a plain JSON body.
          content:
            application/json:
              example:
                Message: >-
                  User is not authorized to access this resource with an
                  explicit deny in an identity-based policy
        '409':
          description: This signature is already pinned to a different target
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.eco.com/v1/errors/signature-already-bound
                title: This signature is already pinned to a different target
                status: 409
                code: signature-already-bound
                requestId: 3ff33e83251b3cdb7d3daf15d186b89b
        '410':
          description: The quote is unknown or expired at submit time
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.eco.com/v1/errors/quote-expired
                title: The quote is unknown or expired at submit time
                status: 410
                code: quote-expired
                requestId: 19ff8aa0914e6fbe2fcb7fbe930bf0ea
        '422':
          description: Chain is not supported
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.eco.com/v1/errors/chain-not-supported
                title: Chain is not supported
                status: 422
                code: chain-not-supported
                requestId: 252dbcdeebe5465fdc089843e8643b37
        '429':
          description: Rate limit exceeded
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.eco.com/v1/errors/rate-limit-exceeded
                title: Rate limit exceeded
                status: 429
                code: rate-limit-exceeded
                requestId: 1eac3d6cc2aafa524b0c47a039576f8c
        '500':
          description: Internal error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.eco.com/v1/errors/internal-error
                title: Internal error
                status: 500
                code: internal-error
                requestId: 02dabcf0f4e3def9a6091526d3d21022
        default:
          description: Error (RFC 9457 problem+json; see x-error-catalog)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - ApiKey: []
components:
  schemas:
    Problem:
      type: object
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
          minLength: 1
        status:
          type: integer
          minimum: 400
          maximum: 599
        code:
          type: string
          description: >-
            Stable, machine-readable error code from the catalog. Branch on this
            and `status`, not on `title` or `detail`.
        detail:
          type: string
        instance:
          type: string
        legacyCode:
          type: string
          description: >-
            The pre-v1 numeric error code this problem maps to, for integrations
            migrating from the older services.
        solverErrors:
          type: array
          items:
            type: object
            properties:
              solver:
                type: string
                description: >-
                  Address on the relevant chain: `0x…` hex for EVM chains,
                  base58 for Solana, `T…` base58 for Tron.
              solverName:
                type: string
                minLength: 1
              code:
                type: string
                minLength: 1
              message:
                type: string
            required:
              - solver
              - message
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
                minLength: 1
              detail:
                type: string
                minLength: 1
            required:
              - field
              - detail
          description: Field-level validation failures.
        requestId:
          type: string
          description: >-
            Correlation ID for support. Present on router-served errors;
            deposit-address-served errors carry a short numeric value.
      required:
        - type
        - title
        - status
        - code
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: x-api-key

````