# Repost a payment's latest webhook

`POST https://api.weavpayments.com/v1/payments/{reference_id}/webhooks/repost`

Sends the payment's latest webhook again, to your current webhook URL, signed with your active key and a fresh `sent_at`. Only finished deliveries can be reposted. Once every 30 seconds per payment (4290201) and up to 20 a minute per account (4290202), API and dashboard together; to check a status, retrieve the payment instead. Proposed.

> **Note:** **To check a payment’s status, [retrieve the payment](https://docs.weavpayments.com/reference/payments/retrieve-payment).** It’s read-only and always has the latest status. A repost sends a signed request to your server each time, so it’s limited. Statuses can’t be set by hand: Weav confirms every result with the provider, and a late one still updates the payment and sends its webhook.

- Only a finished delivery can be reposted. If Weav is still retrying it, you get `409`.
- **Once every 30 seconds per payment**, and **up to 20 a minute** for your account in each mode, through the API and the dashboard together. Over either, you get `429` with a `Retry-After` header. Weav already retries every webhook for about 7 days (see [Retries](https://docs.weavpayments.com/retries#when-weav-retries-a-webhook)), so there’s never a need to repost in bulk.
- The repost is signed with your active signing key and gets a fresh `sent_at`. The event and its `data` stay the same, so handle it idempotently, as with any webhook.
- Every attempt shows under Developers in the dashboard, where you can also repost with one click.

## Errors

A payment with no webhook yet returns `404`. A webhook still being retried returns `409` with code `4090201`. Reposting the same payment within 30 seconds returns `429` with code `4290201`; more than 20 reposts a minute for your account in one mode returns `429` with code `4290202`.

## Path parameters

- `reference_id` (string, required): Weav's payment reference. Pattern: ^PY[0-9A-Z]{12}$.

## Headers

- `Authorization` (string, required): `Bearer` plus your API key. See [Authentication](https://docs.weavpayments.com/authentication).

## Responses

### 202 Accepted

Queued for repost (code 2020200).

What `data` holds:

- `event` (string): One of: `PAYMENT_COMPLETED`, `PAYMENT_FAILED`, `PAYMENT_CANCELLED`, `PAYMENT_REVERSED`, `PAYMENT_REFUNDED`, `CHECKOUT_COMPLETED`, `CHECKOUT_EXPIRED`, `PAYMENT_METHOD_SAVED`, `PAYMENT_METHOD_FAILED`, `PAYMENT_METHOD_REMOVED`, `WITHDRAWAL_COMPLETED`, `WITHDRAWAL_FAILED`.
- `reference_id` (string)

```json
{
    "code": "2020200",
    "success": true,
    "message": "Webhook queued for repost",
    "data": {
        "event": "PAYMENT_COMPLETED",
        "reference_id": "PY7K3Q9M2X4TBA"
    }
}
```

### 401 Unauthorized

Missing, malformed or unknown API key (code 4010000).

```json
{
    "code": "4010000",
    "success": false,
    "message": "Missing or invalid API key."
}
```

### 403 Forbidden

The key can't make this request (code 4030000): an address outside the key's IP allowlist, a live key before your live mode is on, or an account that isn't active. A live key sent from a browser is refused (code 4030001): keep live keys on your server.

```json
{
    "code": "4030000",
    "success": false,
    "message": "Requests with this key must come from an address on its allowlist."
}
```

### 404 Not Found

Not found in this mode for your account (code 4040000).

```json
{
    "code": "4040000",
    "success": false,
    "message": "Not found."
}
```

### 409 Conflict

The request conflicts with the current state, e.g. an Idempotency-Key reused with a different body (4090001), a request still in progress (4090002), a payment that can't be canceled (4090101) or can't be canceled at the provider yet (4090102, retry shortly), or a webhook still being sent (4090201).

```json
{
    "code": "4090001",
    "success": false,
    "message": "This Idempotency-Key was already used with a different request."
}
```

### 429 Too Many Requests

Rate limited (code 4290000). Wait for `Retry-After` seconds.

```json
{
    "code": "4290000",
    "success": false,
    "message": "Too many requests. Wait, then retry."
}
```

## Examples

cURL:

```shell
curl -X POST https://api.weavpayments.com/v1/payments/PY7K3Q9M2X4TBA/webhooks/repost \
    -H "Authorization: Bearer $WEAV_API_KEY"
```

Node.js:

```js
const url =
    'https://api.weavpayments.com/v1/payments/PY7K3Q9M2X4TBA/webhooks/repost';
const response = await fetch(url, {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.WEAV_API_KEY}`,
    },
});

const result = await response.json();
```

JavaScript:

```js
import axios from 'axios';

const response = await axios.request({
    method: 'post',
    url: 'https://api.weavpayments.com/v1/payments/PY7K3Q9M2X4TBA/webhooks/repost',
    headers: {
        Authorization: `Bearer ${process.env.WEAV_API_KEY}`,
    },
    // Read error answers too: their body has the error code.
    validateStatus: () => true,
});

const result = response.data;
```

PHP:

```php
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.weav.key'))
    ->post('https://api.weavpayments.com/v1/payments/PY7K3Q9M2X4TBA/webhooks/repost');

$result = $response->json();
```

Python:

```python
import os
import requests

response = requests.post(
    "https://api.weavpayments.com/v1/payments/PY7K3Q9M2X4TBA/webhooks/repost",
    headers={
        "Authorization": f"Bearer {os.environ['WEAV_API_KEY']}",
    },
    timeout=30,
)

result = response.json()
```

Go:

```go
package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
)

func main() {
    req, err := http.NewRequest("POST", "https://api.weavpayments.com/v1/payments/PY7K3Q9M2X4TBA/webhooks/repost", nil)
    if err != nil {
        panic(err)
    }
    req.Header.Set("Authorization", "Bearer "+os.Getenv("WEAV_API_KEY"))

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer res.Body.Close()

    result, err := io.ReadAll(res.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println(res.Status, string(result))
}
```

Rust:

```rust
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }, serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = std::env::var("WEAV_API_KEY")?;

    let response = reqwest::blocking::Client::new()
        .post("https://api.weavpayments.com/v1/payments/PY7K3Q9M2X4TBA/webhooks/repost")
        .bearer_auth(key)
        .send()?;

    let status = response.status();
    let result: serde_json::Value = response.json()?;
    println!("{status} {result:#}");
    Ok(())
}
```

Java:

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class WeavExample {
    public static void main(String[] args) throws Exception {
        String url = "https://api.weavpayments.com/v1/payments/PY7K3Q9M2X4TBA/webhooks/repost";
        HttpRequest request =
                HttpRequest.newBuilder()
                        .uri(URI.create(url))
                        .header("Authorization", "Bearer " + System.getenv("WEAV_API_KEY"))
                        .method("POST", HttpRequest.BodyPublishers.noBody())
                        .build();

        HttpResponse<String> response =
                HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.statusCode() + " " + response.body());
    }
}
```
