I’m trying to automate daily exchange-rate entry into Manager via API2, ideally using an Access Token so the same approach can later work with Cloud Edition.
Environment
- Manager Server Edition
- Currently 26.9.1.0
- Previously reproduced the same behaviour on 26.6.7.3638
- Windows 11 Pro
- Self-hosted Server Edition
- Base currency for this test business: CAD
- Foreign currency: USD
The USD foreign-currency record is:
Code: USD
Name: US dollar
Key: 7535690f-e02f-4482-b913-75e6da062ffb
The key was confirmed through Batch Update and Manager’s API data.
What works
API2 authentication works correctly using an Access Token and:
X-API-KEY: <token>
For example:
GET /api2/exchange-rates?pageSize=5
returns the expected records.
Fetching an existing valid exchange-rate form also works:
GET /api2/exchange-rate-form/{key}
For a manually created USD rate, I receive something like:
Date : 2026-03-02T00:00:00
Currency : 7535690f-e02f-4482-b913-75e6da062ffb
ExchangeRateValue : 1.3688
The corresponding Exchange Rates list correctly shows:
USD - US dollar
1 USD = 1.3688
The problem
If I POST what appears to be the same data through API2:
POST /api2/exchange-rate-form
Content-Type: application/json
X-API-KEY: <token>
with:
{
"Date": "2099-12-30T00:00:00",
"Currency": "7535690f-e02f-4482-b913-75e6da062ffb",
"ExchangeRateValue": 1.23457
}
Manager returns 200 OK and creates an exchange-rate record.
However, the resulting entry is not initially valid in the UI:
- Currency is blank
- Rate is blank
- Opening Edit shows the UUID as literal text in the Currency selector rather than selecting
USD - US dollar - A later-dated USD invoice does not use that rate
So the API request is accepted, but the Currency relationship does not appear to be resolved correctly.
Using:
"Currency": "USD"
instead produces a 500 Internal Server Error.
Other observations
I also tested the older /api.
PUTon an existing exchange-rate record works correctly.POSTappears to exhibit the same relationship issue as API2.
I then tested Gary Elmes’ exchange-rate extension:
That extension does successfully create new exchange-rate records through API2 on this same Manager installation.
From the source, it appears to POST essentially the same payload:
{
"Date": "...",
"Currency": "<foreign currency key>",
"ExchangeRateValue": ...
}
to:
/api2/exchange-rate-form
The extension obtains foreign-currency keys through API4 and uses an Access Token for API2.
I also confirmed that its browser request has a Manager session cookie attached, but reproducing the PowerShell POST with both the Access Token and the same session cookie did not solve the issue.
One additional oddity: some malformed API-created test rates later appeared correctly in the UI after some time/reloading, but I have not been able to reproduce or explain that reliably, so I would not want to depend on that behaviour.
What I’m trying to determine
Is this the correct way to create a new exchange-rate record through API2?
{
"Date": "YYYY-MM-DDT00:00:00",
"Currency": "<foreign-currency UUID>",
"ExchangeRateValue": 1.23456
}
If so:
- Is there another required field, header, or step needed for Manager to resolve the foreign-currency relationship immediately?
- Why would the same apparent payload work from the custom extension but not from PowerShell/API2 directly?
- Is there a recommended API2/API4 approach for creating exchange rates programmatically?
My eventual goal is fairly simple: retrieve daily rates from Bank of Canada and populate Manager automatically. I would prefer API2 over the legacy API because of Access Token security and because I may move from self-hosted Server Edition to Cloud Edition later.
I’m happy to provide sanitized request/response data or run additional tests if useful.