# toggl-track
`toggl-track` is a general-purpose async Rust library for the Toggl Track API v9.
The crate is intentionally library-first: it contains no CLI, TUI, local database cache, reporting layer, or app-specific configuration storage. It provides typed request/response models around commonly used Toggl Track API operations and leaves application policy to callers.
## Status
Initial development. The current implementation covers the reusable Toggl API client pieces extracted from `toggl-timeguru` and is not yet a complete wrapper for every Toggl Track endpoint.
## Install
```toml
[dependencies]
toggl-track = "0.1"
```
## Quick start
```rust,no_run
use toggl_track::{Result, TogglTrackClient};
#[tokio::main]
async fn main() -> Result<()> {
let client = TogglTrackClient::new("your-api-token")?;
let user = client.current_user().await?;
println!("Authenticated as {}", user.email);
Ok(())
}
```
## Time entries
```rust,no_run
use chrono::{TimeZone, Utc};
use toggl_track::{Result, TogglTrackClient};
#[tokio::main]
async fn main() -> Result<()> {
let client = TogglTrackClient::new("your-api-token")?;
let start = Utc.with_ymd_and_hms(2026, 4, 1, 0, 0, 0).unwrap();
let end = Utc.with_ymd_and_hms(2026, 4, 2, 0, 0, 0).unwrap();
let entries = client.time_entries(start, end).await?;
println!("loaded {} entries", entries.len());
Ok(())
}
```
## Starting and stopping a timer
```rust,no_run
use toggl_track::{Result, StartTimeEntry, TogglTrackClient};
#[tokio::main]
async fn main() -> Result<()> {
let client = TogglTrackClient::new("your-api-token")?;
let workspace_id = 123456;
let started = client
.start_time_entry(&StartTimeEntry::new(workspace_id, "my-app").description("Code review"))
.await?;
let stopped = client.stop_time_entry(workspace_id, started.id).await?;
println!("stopped entry {}", stopped.id);
Ok(())
}
```
## Implemented API surface
- `GET /me`
- `GET /me/time_entries`
- `GET /me/time_entries/current`
- `GET /me/time_entries/{time_entry_id}`
- `POST /workspaces/{workspace_id}/time_entries`
- `PUT /workspaces/{workspace_id}/time_entries/{time_entry_id}`
- `DELETE /workspaces/{workspace_id}/time_entries/{time_entry_id}`
- `PATCH /workspaces/{workspace_id}/time_entries/{time_entry_id}/stop`
- `PATCH /workspaces/{workspace_id}/time_entries/{time_entry_ids}` for bulk edits
- `GET /workspaces`
- `GET /workspaces/{workspace_id}/projects`
See [`docs/GAPS.md`](docs/GAPS.md) for the endpoint and feature gap review.
## Design notes
- Uses `reqwest` with `rustls-tls`.
- Authenticates with a Toggl API token via HTTP Basic auth using `api_token` as the password.
- Tracks `X-Toggl-Quota-Remaining` and `X-Toggl-Quota-Resets-In` headers.
- Provides a configurable base URL and retry policy for tests and callers.
- Uses a crate-specific `Error` type instead of `anyhow`.
## License
MIT