Skip to content

Commit e3136cd

Browse files
pimfeltkampclaude
andcommitted
Fix: send access-token header instead of Authorization: Bearer
Critical: every authenticated request was being rejected by the AWS API Gateway in front of api.cryptohopper.com/v1/*. Switching to access-token: <token> as documented in the official Cryptohopper API docs and used by the legacy iOS/Android SDKs. Bump to 0.4.0a2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 5dd6761 commit e3136cd

5 files changed

Lines changed: 18 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,16 @@
33
All notable changes to the `cryptohopper` Python package are documented in this file.
44
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
55

6-
## 0.4.0a1 — Unreleased
6+
## 0.4.0a2 — Unreleased
7+
8+
### Fixed
9+
- **Critical: every authenticated request was rejected by the API gateway.** The transport sent `Authorization: Bearer <token>`, which the AWS API Gateway in front of `api.cryptohopper.com/v1/*` rejects (it routes `Authorization` to a SigV4 parser and returns `405 Missing Authentication Token`). Cryptohopper's Public API v1 uses `access-token: <token>` instead — confirmed by the official [API documentation](https://www.cryptohopper.com/api-documentation/how-the-api-works) and the legacy `cryptohopper-ios-sdk` / `cryptohopper-android-sdk`. Switching the SDK to send `access-token`. The `Authorization` header is no longer set.
10+
- The `app_key``x-api-app-key` header is unchanged; that one was always correct.
11+
12+
### Compatibility
13+
No public-API change. The fix is purely in the request-builder and is invisible to callers — `client.user.get()`, `client.hoppers.list()`, etc. all keep their existing signatures and behaviour. Only the wire-level header sent on each request changes.
14+
15+
## 0.4.0a1 — 2026-04-25
716

817
Adds four more API domains: `social`, `tournaments`, `webhooks`, `app`. Final A-wave — all 14 remaining public domains now covered.
918

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "cryptohopper"
7-
version = "0.4.0a1"
7+
version = "0.4.0a2"
88
description = "Official Python SDK for the Cryptohopper API"
99
readme = "README.md"
1010
requires-python = ">=3.10"

src/cryptohopper/_client.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,10 @@ def _do_request(
201201
) -> Any:
202202
url = f"{self.base_url}{path if path.startswith('/') else '/' + path}"
203203
headers = {
204-
"Authorization": f"Bearer {self._api_key}",
204+
# Cryptohopper Public API v1 uses `access-token: <token>`, not the
205+
# OAuth2-conventional `Authorization: Bearer <token>`. The gateway
206+
# in front of the API rejects Bearer with a SigV4 parse error.
207+
"access-token": self._api_key,
205208
"User-Agent": self._user_agent(),
206209
"Accept": "application/json",
207210
}

src/cryptohopper/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
CURRENT_VERSION = "0.4.0a1"
1+
CURRENT_VERSION = "0.4.0a2"

tests/test_client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ def test_bearer_user_agent_and_data_unwrap(
2121

2222
req = httpx_mock.get_request()
2323
assert req is not None
24-
assert req.headers["Authorization"] == "Bearer ch_test"
24+
assert req.headers["access-token"] == "ch_test"
25+
assert "Authorization" not in req.headers
2526
assert req.headers["User-Agent"] == f"cryptohopper-sdk-python/{CURRENT_VERSION}"
2627
assert "x-api-app-key" not in req.headers
2728

0 commit comments

Comments
 (0)