Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
541 changes: 541 additions & 0 deletions docs/SDKs/go.md

Large diffs are not rendered by default.

670 changes: 670 additions & 0 deletions docs/SDKs/index.md

Large diffs are not rendered by default.

554 changes: 554 additions & 0 deletions docs/SDKs/java.md

Large diffs are not rendered by default.

1,145 changes: 1,145 additions & 0 deletions docs/SDKs/javascript.md

Large diffs are not rendered by default.

589 changes: 589 additions & 0 deletions docs/SDKs/python.md

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion docs/TurboSign/API Signatures.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ TurboSign offers two single-step endpoints to fit different workflows:
- **Real-time Status Updates**: Track document status throughout the signing process
- **Webhook Integration**: Receive notifications when signing is complete

:::tip Prefer using an SDK?
We offer official SDKs that handle authentication, error handling, and type safety for you.

[View all SDKs →](/docs/SDKs)
:::

## TLDR; Complete Working Example 🚀

Don't want to read all the details? Here's what you need to know:
Expand Down Expand Up @@ -1004,7 +1010,7 @@ Now that you've integrated the single-step signing flow, the next step is settin

### Related Documentation

- [TurboSign Setup Guide](/docs/TurboSign/Setting-up-TurboSign)
- [TurboSign Setup Guide](/docs/TurboSign/Setting%20up%20TurboSign)
- [Webhook Configuration](/docs/TurboSign/Webhooks)
- [API Authentication](/docs/API/turbodocx-api-documentation)
- [Integration Examples](/docs/Integrations)
Expand Down
149 changes: 146 additions & 3 deletions docs/TurboSign/Webhooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,155 @@ Each webhook request includes these headers:

### Try it Now

<ScriptLoader
scriptPath="webhooks/verification"
<ScriptLoader
scriptPath="webhooks/verification"
id="webhook-verification-examples"
label="Webhook Verification Examples"
/>

### SDK Verification Examples

Our SDKs include built-in webhook verification. Here are examples for each language:

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

<Tabs groupId="language">
<TabItem value="js" label="JavaScript" default>

```typescript
import { verifyWebhookSignature } from '@turbodocx/sdk';
import express from 'express';

const app = express();

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const isValid = verifyWebhookSignature({
signature: req.headers['x-turbodocx-signature'],
timestamp: req.headers['x-turbodocx-timestamp'],
body: req.body,
secret: process.env.TURBODOCX_WEBHOOK_SECRET
});

if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}

const event = JSON.parse(req.body.toString());
// Process event...
res.status(200).json({ received: true });
});
```

</TabItem>
<TabItem value="python" label="Python">

```python
from turbodocx import verify_webhook_signature
from fastapi import FastAPI, Request, HTTPException

app = FastAPI()

@app.post("/webhook")
async def handle_webhook(request: Request):
body = await request.body()

is_valid = verify_webhook_signature(
signature=request.headers.get("x-turbodocx-signature"),
timestamp=request.headers.get("x-turbodocx-timestamp"),
body=body,
secret=os.environ["TURBODOCX_WEBHOOK_SECRET"]
)

if not is_valid:
raise HTTPException(status_code=401, detail="Invalid signature")

event = json.loads(body)
# Process event...
return {"received": True}
```

</TabItem>
<TabItem value="go" label="Go">

```go
func webhookHandler(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)

isValid := sdk.VerifyWebhookSignature(
r.Header.Get("X-TurboDocx-Signature"),
r.Header.Get("X-TurboDocx-Timestamp"),
body,
os.Getenv("TURBODOCX_WEBHOOK_SECRET"),
)

if !isValid {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}

var event sdk.WebhookEvent
json.Unmarshal(body, &event)
// Process event...
w.WriteHeader(http.StatusOK)
}
```

</TabItem>
<TabItem value="dotnet" label=".NET">

```csharp
[HttpPost]
public async Task<IActionResult> HandleWebhook()
{
using var reader = new StreamReader(Request.Body);
var body = await reader.ReadToEndAsync();

var isValid = WebhookVerifier.VerifySignature(
Request.Headers["X-TurboDocx-Signature"],
Request.Headers["X-TurboDocx-Timestamp"],
body,
_configuration["TurboDocx:WebhookSecret"]
);

if (!isValid)
return Unauthorized("Invalid signature");

var webhookEvent = JsonSerializer.Deserialize<WebhookEvent>(body);
// Process event...
return Ok(new { Received = true });
}
```

</TabItem>
<TabItem value="ruby" label="Ruby">

```ruby
def turbodocx_webhook
body = request.raw_post

is_valid = TurboDocx::WebhookVerifier.verify(
signature: request.headers['X-TurboDocx-Signature'],
timestamp: request.headers['X-TurboDocx-Timestamp'],
body: body,
secret: ENV['TURBODOCX_WEBHOOK_SECRET']
)

unless is_valid
return render json: { error: 'Invalid signature' }, status: :unauthorized
end

event = JSON.parse(body)
# Process event...
render json: { received: true }
end
```

</TabItem>
</Tabs>

[View full SDK documentation →](/docs/SDKs)

### Security Best Practices

1. **Always verify signatures**: Never process webhooks without verifying the signature
Expand Down Expand Up @@ -390,6 +533,6 @@ If you encounter issues not covered here:

## Next Steps

- [Learn about TurboSign](/docs/TurboSign/Setting-up-TurboSign)
- [Learn about TurboSign](/docs/TurboSign/Setting%20up%20TurboSign)
- [Explore API Documentation](/docs/API/turbodocx-api-documentation)
- [View Integration Guides](/docs/Integrations)
31 changes: 31 additions & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,37 @@
const sidebars = {
mySidebar: [
'Welcome to TurboDocx',
{
type: 'category',
label: 'SDKs',
collapsed: false,
link: {
type: 'doc',
id: 'SDKs/index',
},
items: [
{
type: 'doc',
id: 'SDKs/javascript',
label: 'JavaScript / TypeScript',
},
{
type: 'doc',
id: 'SDKs/python',
label: 'Python',
},
{
type: 'doc',
id: 'SDKs/go',
label: 'Go',
},
{
type: 'doc',
id: 'SDKs/java',
label: 'Java',
},
],
},
{
type: 'category',
label: 'TurboDocx Templating',
Expand Down