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

# Accept

> Accepts a dual hedge rate proposal and books both customer and supplier hedge legs at their proposed rates and tenors.



## OpenAPI

````yaml POST /customers/{customerId}/dual-hedges/accept-offline-quote
openapi: 3.1.0
info:
  title: Grain API
  version: 1.0.0
  description: >-
    Grain's API provides a comprehensive set of endpoints for managing hedging,
    spot transactions, pricing, and fund movements - enabling seamless
    integration of FX workflows into your platform. Each API call follows REST
    conventions, uses secure authentication, and returns standardized responses
    for consistency across environments.
  license:
    name: Creative Commons Attribution 3.0
  contact:
    name: Grain Finance
    url: https://docs.grainfinance.co
    email: support@grainfinance.co
  termsOfService: https://grainfinance.co/terms-of-service/
  x-apiClientRegistration:
    url: https://grainfinance.co/partners
servers:
  - url: https://api.grainfinance.co/v1
    description: Grain API
security: []
tags:
  - name: Hedges
    description: >-
      Hedge objects represent transactions that lock exchange rates for future
      dates. A single hedge locks an exchange rate for a future transaction
      between two currencies.
  - name: Dual Hedges
    description: >-
      A dual hedge mitigates FX risk by automatically generating two linked
      hedge legs - a customer leg and a supplier leg - both routed through the
      customer's functional currency. This structure reduces exposure to
      currency fluctuations for both cash flow and accounting purposes, while
      allowing independent tracking and reporting of each hedge leg.
  - name: Customers
    description: >-
      Customer objects represent your end customers on the Grain platform. A
      customer must be created before a hedge or spot transaction can be
      initiated.
  - name: Pricing
    description: >-
      Pricing endpoints provide access to FX rates for currency pairs that are
      not being hedged. These endpoints can be used for live rate display or
      bulk retrieval to support high-volume quoting workflows.
  - name: Spots
    description: >-
      Spot objects represent currency conversions executed for immediate or
      near-term settlement.
  - name: Conversions
    description: >-
      Conversion objects represent currency conversions executed for immediate
      or near-term settlement.
  - name: Wallets
    description: Endpoints to view balances, manage funding, and perform transfers.
paths:
  /customers/{customerId}/dual-hedges/accept-offline-quote:
    post:
      tags:
        - Dual Hedges
      description: >-
        Accepts a dual hedge rate proposal and books both customer and supplier
        hedge legs at their proposed rates and tenors.
      operationId: Offline Accept
      parameters:
        - description: The id of the customer within the Grain platform.
          in: path
          name: customerId
          required: true
          schema:
            type: string
        - in: header
          name: X-Customer-IP
          required: true
          schema:
            $ref: '#/components/schemas/CustomerIP'
      requestBody:
        description: The payload required to accept an offline quote for a dual hedge
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AcceptOfflineDualHedgeProposalRequestBody'
              description: The payload required to accept an offline quote for a dual hedge
      responses:
        '200':
          description: Dual Hedge Accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AcceptOfflineDualHedgeResponseBody'
        '400':
          description: >-
            The request failed because it is not well-formed or is syntactically
            incorrect or violates schema.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AcceptOfflineHedgeBadParamsErrorResponse'
        '401':
          description: >-
            Authentication failed due to missing authorization header, or
            invalid authentication credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: The request failed because the resource does not exist.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: The request failed because a business rule constraint was violated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: The request failed because one or more preconditions were not met.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            The request failed because it is either semantically incorrect or
            has failed business validation.
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/AcceptOfflineHedgeRevisionExpiredErrorResponse
        '428':
          description: The request failed because a required precondition was not provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '451':
          description: The request failed due to legal restrictions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RejectedByIPError'
      security:
        - api-key: []
components:
  schemas:
    CustomerIP:
      type: string
      format: IPv4
      description: >-
        The IPv4 address of the browser from which the customer contacts your
        platform. <br />

        _example_: `192.158.1.38`
      pattern: ((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}
    AcceptOfflineDualHedgeProposalRequestBody:
      properties:
        revision:
          type: number
          format: double
          description: >-
            The id of the revision that defines the accepted rate for the
            currency-pair and tenor.
          example: 156
        fromCurrency:
          type: string
          description: >-
            The currency in which the transaction should be paid by your
            customer.
          example: MXN
        toCurrency:
          type: string
          description: The currency you want to buy.
          example: USD
        customerToCurrencyAmount:
          type: number
          format: double
          description: The amount to hedge in the toCurrency for the customer.
          example: 100000
        vendorToCurrencyAmount:
          type: number
          format: double
          description: The amount to hedge in the toCurrency for the vendor.
          example: 100000
        customerEndAt:
          type: string
          description: >-
            The date in which the customer hedge will be settled, denoted in
            `YYYY-MM-DD` format.
          example: '2024-02-23'
        vendorEndAt:
          type: string
          description: >-
            The date in which the vendor hedge will be settled, denoted in
            `YYYY-MM-DD` format.
          example: '2024-02-23'
        rate:
          type: number
          format: double
          description: >-
            Represents the offline hedge rate determined by a two-dimensional
            lookup based on the vendor and customer tenors.


            **Calculating Tenors:**


            Tenors are calculated from the calendar-day difference between the
            tenorCalculationDate and the vendor/customer end dates, then mapped
            into the nearest supported tenor bucket:


            -

            - > 0 and ≤ 7 calendar days → 7-day tenor

            - > 7 and ≤ 14 calendar days → 14-day tenor

            - > 14 and ≤ 30 calendar days → 30-day tenor

            - > 30 and ≤ 60 calendar days → 60-day tenor

            - > 60 and ≤ 90 calendar days → 90-day tenor

            - … continues in similar ranges up to 720 days


            **Note:** All calendar days count — weekends and holidays included.


            **Rate Lookup Example:**


            The rate is retrieved from a two-dimensional map using both tenors:

            ```

            "USDMXN": {
              "7": { "7": 1.1 },
              "14": { "7": 1.2, "14": 1.3 },
              "30": { "7": 1.1, "14": 1.1, "30": 1.1 },
              // ... and so on
            }

            ```


            In this example, if the vendor tenor is 14 days and the customer
            tenor is 7 days, the rate would be 1.2.


            To calculate the difference in calendar days accurately, we
            recommend using a date manipulation library, such as date-fns and
            its `differenceInCalendarDays` function, or a similar feature
            provided by other date libraries.
          example: 20.616512
        externalTransactionId:
          type: string
          description: The transaction id, as identified within your system.
          example: 780231b3ae0d7e9e5097nd89
        extraFields:
          $ref: '#/components/schemas/ExtraFieldsParam'
      required:
        - revision
        - fromCurrency
        - toCurrency
        - customerToCurrencyAmount
        - vendorToCurrencyAmount
        - customerEndAt
        - vendorEndAt
        - rate
        - externalTransactionId
      type: object
      additionalProperties: false
    AcceptOfflineDualHedgeResponseBody:
      description: The response of accepting an offline rate for a dual hedge.
      properties:
        id:
          $ref: '#/components/schemas/UUID'
          description: The id of the dual hedge within the Grain platform.
          example: 8173b9a7-ee61-413e-b9e3-7c04b2a067c5
        transactionId:
          $ref: '#/components/schemas/UUID'
          description: The id of the transaction within the Grain platform.
          example: 4d78ac65-2c3f-47e2-8bf3-3f76124e9d27
        hedgeIds:
          items:
            $ref: '#/components/schemas/UUID'
          type: array
          description: The ids of the individual hedges created as part of this dual hedge.
          example:
            - 4d78ac65-2c3f-47e2-8bf3-3f76124e9d27
            - 5e89bd76-3d4f-58e3-9cf4-4g87235e0e38
      required:
        - id
        - hedgeIds
      type: object
      additionalProperties: false
    AcceptOfflineHedgeBadParamsErrorResponse:
      description: An API Error
      properties:
        message:
          type: string
          description: A short code of the error.
          example: REVISION_INVALID
        reason:
          type: string
          description: A detailed description of the reason for the failure.
          example: >-
            The revision number is not valid or does not exist. Please fetch a
            new rate table using the /offline-rates endpoint and pass a valid
            revision.
      required:
        - message
      type: object
      additionalProperties: false
    ErrorResponse:
      description: An API Error
      properties:
        message:
          type: string
          description: A short explanation of the error.
          example: Can't perform this action
        reason:
          type: string
          description: A detailed description of the reason for the failure.
          example: >-
            Supplied object is in *Cancelled* state, which prevents performing
            this action
      required:
        - message
      type: object
      additionalProperties: false
    AcceptOfflineHedgeRevisionExpiredErrorResponse:
      description: An API Error
      properties:
        message:
          type: string
          description: A short code of the error.
          example: REVISION_EXPIRED
        reason:
          type: string
          description: A detailed description of the reason for the failure.
          example: >-
            The revision number has expired. Please fetch a new rate table using
            the /offline-rates endpoint.
      required:
        - message
      type: object
      additionalProperties: false
    RejectedByIPError:
      properties:
        message:
          type: string
          description: A short explanation of the error.
          example: Could not parse IP address (v4 or v6) for ip
      required:
        - message
      type: object
      additionalProperties: false
    ExtraFieldsParam:
      properties: {}
      additionalProperties:
        anyOf:
          - type: string
          - type: number
            format: double
          - type: boolean
      type: object
      example:
        field_a: value_a
        field_b: value_b
      description: |-
        Additional fields that provide further details about the transaction.
        These fields should be specified as a valid JSON object.
    UUID:
      type: string
      format: uuid
      description: |-
        Stringified UUIDv4.
        See [RFC 4112](https://tools.ietf.org/html/rfc4122)
      pattern: >-
        [0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-4[0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}
  securitySchemes:
    api-key:
      type: http
      scheme: basic
      description: >-
        Basic authentication using the partner API keys from
        https://console.grainfinance.co/keys

````