carejobs-crystal
carejobs-crystal
Crystal client for the CareJobs.Now healthcare jobs API. Search open US healthcare jobs, see the hourly pay employers post, and look up employers and states.
- Free, no API key.
- Standard library only (
HTTP::Client,JSON). Crystal 1.0 or newer. - Typed results (
JSON::Serializableclasses), oneCareJobs::Errortype. - The same API is a remote MCP server at https://carejobs.now/api/mcp, so any MCP client can use it too.
Install
Add the shard to your shard.yml:
dependencies:
carejobs:
github: yumaheymans/carejobs-crystal
Then run shards install.
Quick start
require "carejobs"
client = CareJobs::Client.new
res = client.search_jobs(query: "ICU", kind: CareJobs::Kind::Nurses, state: "TX", limit: 5)
puts "#{res.total} jobs match"
res.jobs.each do |job|
puts "#{job.title} | #{job.employer} | #{job.location} | #{job.url}"
end
pay = client.pay_by_kind(CareJobs::Kind::Nurses)
if stats = pay.pay
puts "Median posted pay for nurses: $#{stats.median}/hr"
end
Methods
| Method | What it answers | Result |
|---|---|---|
Client.new(base_url, timeout, user_agent) |
Settings for the calls | Client |
search_jobs(query, kind, state, limit) |
Open jobs by words, kind, state and limit | SearchResult |
pay_by_kind(kind) |
Posted hourly pay for one kind of job, and the employers posting the most | PayResult |
employers(query, limit) |
The employers, AI-training programs and job boards the site reads | EmployerList |
states |
Open jobs in every US state | Array(StateSummary) |
CareJobs.kinds |
The 17 kinds of job (no request) | Array(Kind) |
call_tool(name, arguments) |
Any tool of the server, as raw JSON | JSON::Any |
Every filter is optional (nil leaves it off). CareJobs::Kind is an enum with the 17 kinds; kind.slug is the string the API uses ("nurse-practitioners"), and Kind.from_slug?("nurses") reads one back.
Every Job carries url, its page on CareJobs.Now, where a person applies. The server has no separate job lookup by id: a job is described by the search answer.
Where the API sends null, the field is nil (Job#pay, SearchResult#pay, PayResult#pay, and so on): PayResult#pay is nil when too few jobs post an hourly rate to measure.
Errors and timeouts
Every failure (network, HTTP status, JSON-RPC error, a tool the server refuses to run) raises CareJobs::Error, which has status (the HTTP status, if any) and tool.
begin
client.search_jobs(state: "TX")
rescue ex : CareJobs::Error
puts "#{ex.message} (HTTP #{ex.status})"
end
The default timeout is 60 seconds. The server answers a query it has not seen before in up to about 25 seconds (its database may be waking up), then repeats of it in a fraction of one. Change it with CareJobs::Client.new(timeout: 2.minutes).
Development
crystal spec # offline: recorded answers and a local test server
crystal run examples/live.cr # the same calls against the real API
Data
Data from CareJobs.Now, CC BY 4.0. Docs and downloads: https://carejobs.now/data.
License
Code: MIT, copyright O-mega Enterprise, Inc. See LICENSE.
carejobs-crystal
- 0
- 0
- 0
- 0
- 0
- about 7 hours ago
- October 20, 2026
MIT License
Tue, 20 Oct 2026 11:25:55 GMT