toggl-track 0.1.0

General-purpose async Rust library for the Toggl Track API v9
Documentation
# 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