linkshieldai 0.2.0

Rust SDK for the LinkShieldAI URL safety API.
Documentation
# LinkShieldAI Rust SDK

New integrations should use `client.scan(url, mode).await`, which calls Bearer-authenticated `POST /v1/scan`. Existing methods remain for compatibility.

```rust
let client = linkshieldai::LinkShieldAI::new(std::env::var("LINKSHIELDAI_API_KEY")?)?;
let result = client.scan("https://example.com", "standard").await?;
println!("{} {}", result.verdict, result.request_id);
```

`UNKNOWN` means the API found no decisive signal. Do not treat it as `SAFE`.

Rust SDK for the LinkShieldAI API at `https://api.linkshieldai.com`.

The SDK supports basic URL safety checks, detailed checks with screenshot URL and detected tag, screenshot download, NSFW site checks, Chimera AI classification, retry/backoff for transient API failures, and a small command-line tool.

## Install


```toml
[dependencies]
linkshieldai = "0.2"
```

## Authentication


Every SDK request sends the key as an `Authorization: Bearer` header. Legacy endpoints receive only the URL as a query parameter.

```rust
use linkshieldai::LinkShieldAI;

#[tokio::main]

async fn main() -> linkshieldai::Result<()> {
    let client = LinkShieldAI::new("YOUR_API_KEY".to_string())?;

    let result = client.basic_check("https://example.com").await?;
    println!("{:?}", result.result);
    println!("{}", result.is_malicious);

    Ok(())
}
```

Or set `LINKSHIELDAI_API_KEY` and pass an empty string:

```rust
let client = LinkShieldAI::new("")?;
```

## Methods


```rust
let basic = client.basic_check("https://example.com").await?;
let detailed = client.detailed_check("https://example.com").await?;
let nsfw = client.nsfw_check("https://example.com").await?;
let chimera = client.chimera("https://google.com").await?;
let is_malicious = client.is_malicious("https://example.com").await?;
let is_nsfw = client.is_nsfw("https://example.com").await?;
let bytes = client.get_screenshot("05046f.png", Some("site.png".as_ref())).await?;
```

The API field `"screenshot url"` is normalized to `screenshot_url`.

## Options


```rust
use std::time::Duration;
use linkshieldai::LinkShieldAI;

let client = LinkShieldAI::builder()
    .api_key("YOUR_API_KEY")
    .base_url("https://api.linkshieldai.com")
    .timeout(Duration::from_secs(15))
    .max_retries(3)
    .backoff_factor(Duration::from_secs(1))
    .build()?;
```

By default the SDK uses:

- `timeout`: 10 seconds
- `max_retries`: 2
- `backoff_factor`: 500 ms

Retries are applied to temporary connection failures and HTTP `429`, `502`, `503`, and `504`.

## CLI


```bash
cargo run --bin linkshieldai -- --api-key YOUR_API_KEY scan https://example.com --mode standard
cargo run --bin linkshieldai -- --api-key YOUR_API_KEY scan https://example.com --mode detailed
cargo run --bin linkshieldai -- --api-key YOUR_API_KEY scan https://example.com --mode deep
cargo run --bin linkshieldai -- --api-key YOUR_API_KEY basic https://example.com
cargo run --bin linkshieldai -- --api-key YOUR_API_KEY detailed https://example.com
cargo run --bin linkshieldai -- --api-key YOUR_API_KEY nsfw https://example.com
cargo run --bin linkshieldai -- --api-key YOUR_API_KEY chimera https://google.com
cargo run --bin linkshieldai -- --api-key YOUR_API_KEY screenshot 05046f.png --output site.png
```

You can omit `--api-key` if `LINKSHIELDAI_API_KEY` is set.

## Errors


```rust
match error {
    linkshieldai::LinkShieldAIError::RateLimit { retry_after } => {
        // handle rate limit
    }
    other => return Err(other),
}
```

Raw API payloads are preserved on result structs through `raw`.

Keep API keys server-side.