hackerone-api 0.1.0

Unofficial, dependency-light Rust client for the HackerOne API (v1).
Documentation
# hackerone-api

Unofficial, dependency-light Rust client for the [HackerOne API][api] (v1).

Blocking, no async runtime. HTTP Basic auth. An injectable transport so tests
use a mock and embedders can swap the HTTP stack.

```rust
use hackerone_api::{Client, ReportQuery};

fn main() -> Result<(), hackerone_api::Error> {
    let client = Client::new("api-identifier", "api-token");

    for program in client.programs()?.items() {
        println!("{:?}", program.handle);
    }

    let reports = client
        .reports(&ReportQuery::new().state("new").page(1, 25))?
        .into_items();
    println!("{} new reports", reports.len());
    Ok(())
}
```

## Auth

The API uses HTTP Basic auth: the **username** is your API token *identifier*
and the **password** is the token *value*. Create a token in your HackerOne
account settings, then:

```sh
export HACKERONE_API_IDENTIFIER="..."
export HACKERONE_API_TOKEN="..."
cargo run --example list_reports
```

Never commit a token. In AXIOM, seed it in the vault
(`ax-vault put persona/smurf77/hackerone hackerone-api`) and inject it at call
time.

## Surface (v0.1)

| Method | Endpoint |
|---|---|
| `me()` | `GET /v1/me` |
| `programs()` | `GET /v1/me/programs` |
| `program(id)` | `GET /v1/programs/{id}` |
| `structured_scopes(program, page)` | `GET /v1/programs/{id}/structured_scopes` |
| `reports(query)` | `GET /v1/reports` |
| `report(id)` | `GET /v1/reports/{id}` |
| `create_report(report)` | `POST /v1/reports` |
| `add_comment(report, text)` | `POST /v1/reports/{id}/activities` |
| `change_state(report, state, msg)` | `POST /v1/reports/{id}/state_changes` |
| `weaknesses()` | `GET /v1/weaknesses` |
| `next_page(&page)` | follows a `links.next` URL |
| `get_raw(path, query)` | any authenticated GET |

Domain types (`Report`, `Program`, `StructuredScope`, `User`, `Weakness`, …)
carry the documented fields and keep unknown ones in a flattened `extra` map,
so a server-side field addition never breaks a decode.

## Design

- `#![forbid(unsafe_code)]`, `#![warn(missing_docs)]`.
- Errors are typed: `Error::{Transport, Decode, Invalid, Api}`; `Api` carries
  the HTTP status and the parsed `errors` array.
- Transport is a trait (`Transport`); `UreqTransport` is the default.
- Tests run entirely against a mock transport — no network.

## Status

`0.1.0` — early. The endpoint coverage is the documented v1 surface most used
by tooling; additional endpoints land as needed. Issues and PRs welcome.

## License

MIT. See [LICENSE](LICENSE).

## Disclaimer

This crate is unofficial and not affiliated with or endorsed by HackerOne.
"HackerOne" is a trademark of its owner; the name is used only to describe
what the library talks to.

[api]: https://api.hackerone.com/