# Accessing Google APIs via Crystal

**URL:** <https://forum.crystal-lang.org/t/accessing-google-apis-via-crystal/9196>\
**Category:** Community\
**Created:** [October 8, 2026, 11:17pm UTC](https://forum.crystal-lang.org/t/accessing-google-apis-via-crystal/9196 "2026-10-08T23:17:18Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![nbrandaleone](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nbrandaleone/32/2224_2.png) [@nbrandaleone](https://forum.crystal-lang.org/u/nbrandaleone)\
**Post date:** [October 8, 2026, 11:17pm UTC](https://forum.crystal-lang.org/t/accessing-google-apis-via-crystal/9196/1 "2026-10-08T23:17:18Z")

</div>

Hi,

I work with Google Cloud often, and typically use Ruby to interface with the APIs. Ruby is an official SDK of Google Cloud. However, I prefer these days to things in Crystal if possible (it is all about speed!). However, crystal is not an official SDK of Google.

Well, I was able to write a generator that creates crystal shards from the Google Discovery docs (similar to openSDK specs). This is similar to how almost all the official languages are generated these days. The most recent language (Rust) acknowledges this in the README.

At the moment, there is only one library generated (Cloud Storage), but I am working on generating all the SDKs. Of course, when I say I wrote the code, I really meant that I worked with an AI tool to create it. Thus, it is not idiomatic - but it works… :-)

Please see: [GitHub - nbrandaleone-gcp/google-apis-cr: A library (shard) that generates Crystal code for interacting with Google APIs. · GitHub](https://github.com/nbrandaleone-gcp/google-apis-cr)

Nick Brandaleone

---

<div class="post-metadata">

**Author:** ![rachelwilson](https://avatars.discourse-cdn.com/v4/letter/r/8edcca/32.png) [@rachelwilson](https://forum.crystal-lang.org/u/rachelwilson)\
**Post date:** [October 9, 2026, 12:21am UTC](https://forum.crystal-lang.org/t/accessing-google-apis-via-crystal/9196/2 "2026-10-09T00:21:51Z")

</div>

really neat idea, generating the shards from the discovery docs is basically how the official clients stay in sync, so that should age well. cloud storage is a solid first one too. auth is usually the fiddly part with these, are you planning to bake in oauth and service account support or leaving that to the user.

---

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [October 9, 2026, 3:11am UTC](https://forum.crystal-lang.org/t/accessing-google-apis-via-crystal/9196/3 "2026-10-09T03:11:25Z")

</div>

I started writing something to handle discovery with [my `google` shard](https://github.com/jgaskins/google), but as you can see [here](https://github.com/jgaskins/google/blob/main/discover.cr), I never got anywhere with it. 😄 I had immediate problems to solve and needed to get the Auth, Calendar, Drive, and People APIs working. Since then, I’ve added Gemini, Gmail, Maps, Places, Tasks, Storage, and BigQuery.

---

<div class="post-metadata">

**Author:** ![nbrandaleone](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nbrandaleone/32/2224_2.png) [@nbrandaleone](https://forum.crystal-lang.org/u/nbrandaleone)\
**Post date:** [October 9, 2026, 1:02pm UTC](https://forum.crystal-lang.org/t/accessing-google-apis-via-crystal/9196/4 "2026-10-09T13:02:36Z")

</div>

Rachel - you are correct that authorization is usually a problem with these types of libraries. For now, I am supporting “Application Default Credentials”, which basically grabs a token at a known location. I am working on service account credentials support, but it has not been fully implemented yet.

## **3. Authentication Implementation (`src/google_apis/auth.cr`)**

- **Resolution Precedence** :
  1. `$GOOGLE_APPLICATION_CREDENTIALS` environment variable.
  2. Well-known user ADC file: `~/.config/gcloud/application_default_credentials.json` (or `%APPDATA%/gcloud/...` on Windows).

- **AuthorizedUserCredentials** :
  - Exposes `authorization_header` (`"Bearer <token>"`).
  - Proactive token caching and refresh: refreshes whenever expired or within 60 seconds of expiration.
  - Thread- and fiber-safe access via `Mutex`.
  - Exposes `project_id` and `quota_project_id`.
  - Redacts sensitive secrets in `#inspect` and `#to_s` to prevent leakage into logs.

- **ServiceAccountCredentials** :
  - Parses service account JSON metadata.
  - Raises `UnsupportedCredentialsTypeError` explaining that RS256 JWT signing requires cryptography shards beyond Crystal’s standard library.

- **Unit Specs** : Mock HTTP server testing resolution, token refresh, caching, and error handling (`spec/google_apis/auth_spec.cr`).

---

<div class="post-metadata">

**Author:** ![nbrandaleone](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nbrandaleone/32/2224_2.png) [@nbrandaleone](https://forum.crystal-lang.org/u/nbrandaleone)\
**Post date:** [October 9, 2026, 1:04pm UTC](https://forum.crystal-lang.org/t/accessing-google-apis-via-crystal/9196/5 "2026-10-09T13:04:52Z")

</div>

Your library was an inspiration to me! You have covered most of the popular services, and it is idiomatic to boot! This library will have fuller coverage of Cloud APIs, but will not be idiomatic due to the AI tool writing most of the code.

Nick

---

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [October 9, 2026, 9:43pm UTC](https://forum.crystal-lang.org/t/accessing-google-apis-via-crystal/9196/6 "2026-10-09T21:43:54Z")

</div>

> [@nbrandaleone](#):
>
> I am working on service account credentials support, but it has not been fully implemented yet.

Feel free to borrow mine. I built it into my GCS implementation:

- [`ServiceAccount::Key`](https://github.com/jgaskins/google/blob/a30d66547f841fae82e3ef569e4c790c9b96290d/src/service_account.cr#L3-L20) — you copy and paste the ServiceAccount JSON into an app then use `Google::ServiceAccount::Key.from_json(json)`
- [Access token generation](https://github.com/jgaskins/google/blob/a30d66547f841fae82e3ef569e4c790c9b96290d/src/cloud/storage.cr#L159-L182)
- [JWT encoding on-the-fly needed for the access token generation](https://github.com/jgaskins/google/blob/a30d66547f841fae82e3ef569e4c790c9b96290d/src/cloud/storage.cr#L207-L218)

Haven’t gotten around to generalizing it yet because GCS is the only thing I’ve been using ServiceAccounts for.

---

<div class="post-metadata">

**Author:** ![nbrandaleone](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nbrandaleone/32/2224_2.png) [@nbrandaleone](https://forum.crystal-lang.org/u/nbrandaleone)\
**Post date:** [October 9, 2026, 10:44pm UTC](https://forum.crystal-lang.org/t/accessing-google-apis-via-crystal/9196/7 "2026-10-09T22:44:52Z")

</div>

Thank you. I will see if I can integrate the code next week.  
I appreciate it.

Nick
