API2 POST to /exchange-rate-form creates invalid/blank Currency relationship

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.

  • PUT on an existing exchange-rate record works correctly.
  • POST appears 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:

  1. Is there another required field, header, or step needed for Manager to resolve the foreign-currency relationship immediately?
  2. Why would the same apparent payload work from the custom extension but not from PowerShell/API2 directly?
  3. 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.

1 Like