curl --request POST \
--url https://api.grainfinance.co/v1/conversions/quote \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--header 'X-Customer-IP: <x-customer-ip>' \
--data '
{
"fromCurrency": "MXN",
"toCurrency": "USD",
"toCurrencyAmount": 1560
}
'import requests
url = "https://api.grainfinance.co/v1/conversions/quote"
payload = {
"fromCurrency": "MXN",
"toCurrency": "USD",
"toCurrencyAmount": 1560
}
headers = {
"X-Customer-IP": "<x-customer-ip>",
"Authorization": "Basic <encoded-value>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Customer-IP': '<x-customer-ip>',
Authorization: 'Basic <encoded-value>',
'Content-Type': 'application/json'
},
body: JSON.stringify({fromCurrency: 'MXN', toCurrency: 'USD', toCurrencyAmount: 1560})
};
fetch('https://api.grainfinance.co/v1/conversions/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.grainfinance.co/v1/conversions/quote",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'fromCurrency' => 'MXN',
'toCurrency' => 'USD',
'toCurrencyAmount' => 1560
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: application/json",
"X-Customer-IP: <x-customer-ip>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.grainfinance.co/v1/conversions/quote"
payload := strings.NewReader("{\n \"fromCurrency\": \"MXN\",\n \"toCurrency\": \"USD\",\n \"toCurrencyAmount\": 1560\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Customer-IP", "<x-customer-ip>")
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.grainfinance.co/v1/conversions/quote")
.header("X-Customer-IP", "<x-customer-ip>")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"fromCurrency\": \"MXN\",\n \"toCurrency\": \"USD\",\n \"toCurrencyAmount\": 1560\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.grainfinance.co/v1/conversions/quote")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Customer-IP"] = '<x-customer-ip>'
request["Authorization"] = 'Basic <encoded-value>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fromCurrency\": \"MXN\",\n \"toCurrency\": \"USD\",\n \"toCurrencyAmount\": 1560\n}"
response = http.request(request)
puts response.read_body{
"id": "8173b9a7-ee61-413e-b9e3-7c04b2a067c5",
"fromCurrency": "MXN",
"toCurrency": "USD",
"quote": 20.6165,
"validUntilTs": 1659625098,
"toCurrencyAmount": 1560,
"fromCurrencyAmount": 32161.8
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Could not parse IP address (v4 or v6) for ip"
}Quote
Generates a conversion rate proposal for a new currency conversion.
curl --request POST \
--url https://api.grainfinance.co/v1/conversions/quote \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--header 'X-Customer-IP: <x-customer-ip>' \
--data '
{
"fromCurrency": "MXN",
"toCurrency": "USD",
"toCurrencyAmount": 1560
}
'import requests
url = "https://api.grainfinance.co/v1/conversions/quote"
payload = {
"fromCurrency": "MXN",
"toCurrency": "USD",
"toCurrencyAmount": 1560
}
headers = {
"X-Customer-IP": "<x-customer-ip>",
"Authorization": "Basic <encoded-value>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Customer-IP': '<x-customer-ip>',
Authorization: 'Basic <encoded-value>',
'Content-Type': 'application/json'
},
body: JSON.stringify({fromCurrency: 'MXN', toCurrency: 'USD', toCurrencyAmount: 1560})
};
fetch('https://api.grainfinance.co/v1/conversions/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.grainfinance.co/v1/conversions/quote",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'fromCurrency' => 'MXN',
'toCurrency' => 'USD',
'toCurrencyAmount' => 1560
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: application/json",
"X-Customer-IP: <x-customer-ip>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.grainfinance.co/v1/conversions/quote"
payload := strings.NewReader("{\n \"fromCurrency\": \"MXN\",\n \"toCurrency\": \"USD\",\n \"toCurrencyAmount\": 1560\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Customer-IP", "<x-customer-ip>")
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.grainfinance.co/v1/conversions/quote")
.header("X-Customer-IP", "<x-customer-ip>")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"fromCurrency\": \"MXN\",\n \"toCurrency\": \"USD\",\n \"toCurrencyAmount\": 1560\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.grainfinance.co/v1/conversions/quote")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Customer-IP"] = '<x-customer-ip>'
request["Authorization"] = 'Basic <encoded-value>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fromCurrency\": \"MXN\",\n \"toCurrency\": \"USD\",\n \"toCurrencyAmount\": 1560\n}"
response = http.request(request)
puts response.read_body{
"id": "8173b9a7-ee61-413e-b9e3-7c04b2a067c5",
"fromCurrency": "MXN",
"toCurrency": "USD",
"quote": 20.6165,
"validUntilTs": 1659625098,
"toCurrencyAmount": 1560,
"fromCurrencyAmount": 32161.8
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Can't perform this action",
"reason": "Supplied object is in *Cancelled* state, which prevents performing this action"
}{
"message": "Could not parse IP address (v4 or v6) for ip"
}Authorizations
Basic authentication using the partner API keys from https://console.grainfinance.co/keys
Headers
The IPv4 address of the browser from which the customer contacts your platform.
example: 192.158.1.38
((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}Body
Information required by Grain in order to generate a conversion quote proposal.
The currency in which the transaction should be paid at by your customer.
^[A-Z]{3}$"MXN"
The currency in which the inventory item is listed at on your platform.
^[A-Z]{3}$"USD"
The amount of toCurrency to convert, using this amount and the conversion rate will determine the fromCurrency amount.
1560
Response
Conversion Proposal Created
The id of the conversion proposal within the Grain platform.
[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}"8173b9a7-ee61-413e-b9e3-7c04b2a067c5"
The original currency that will be converted into a different currency. This is the currency the user wants to exchange or convert in the transaction.
"MXN"
The target currency that the original currency (fromCurrency) will be converted into. This is the desired currency after the conversion process is complete.
"USD"
The rate locked by this conversion.
20.6165
The unix timestamp until which the conversion offer is valid.
1659625098
The amount to transfer in the toCurrency
1560
The amount to transfer in the fromCurrency
32161.8