.NET
Complete reference for the Pogodoc .NET SDK with types, advanced configuration, and examples
.NET SDK
Complete documentation for the Pogodoc .NET SDK. This guide covers installation, configuration, all available methods, and advanced usage patterns.
New to Pogodoc? Start with the .NET Quickstart guide first.
Quick Links
- Installation
- Client Configuration
- Core Methods
- Template Management
- Using Saved Templates
- Best Practices
- Examples
Installation
dotnet add package Pogodoc.NetOr via NuGet Package Manager:
Install-Package Pogodoc.NetClient Configuration
Basic Configuration
using Pogodoc.Net;
var client = new PogodocClient("your-api-token");With Base URL
var client = new PogodocClient(
token: "your-api-token",
baseUrl: "https://api.pogodoc.com"
);Environment Variables
Configure using environment variables:
// Token from environment variables
var token = Environment.GetEnvironmentVariable("POGODOC_API_TOKEN");
var client = new PogodocClient(token);{
"Pogodoc": {
"ApiToken": "your_token_here",
"BaseUrl": "https://api.pogodoc.com"
}
}The constructor requires a valid token. Ensure the token is provided either directly or via environment variables.
Core Methods
The SDK provides both synchronous and asynchronous methods for document generation and template management.
GenerateDocumentAsync()
The recommended method for most use cases. Generates a document and polls for completion automatically.
using Pogodoc.Net;
var client = new PogodocClient("your-token");
var result = await client.GenerateDocumentAsync(
templateId: "your-template-id",
data: new Dictionary<string, object>
{
["name"] = "Jane Doe",
["amount"] = 1299.99
},
renderConfig: new RenderConfig
{
Type = TemplateType.React,
Target = RenderTarget.Pdf
}
);
Console.WriteLine($"Document URL: {result.Output.Data.Url}");Parameters:
template(optional): Raw HTML/template stringtemplateId(optional): ID of a saved templatedata: Dictionary containing data to populate the templaterenderConfig:RenderConfigobject with:Type: Template format typeTarget: Output formatFormatOpts(optional): Format-specific options
Important: You must provide either template or templateId, but not
both. Exactly one is required.
Returns: Task<JobStatusResponse> - Job status with the final output URL
GenerateDocumentImmediateAsync()
For quick, synchronous rendering of small documents. Returns the result immediately without job polling.
var result = await client.GenerateDocumentImmediateAsync(
templateId: "your-template-id",
data: new Dictionary<string, object>
{
["name"] = "Jane Doe"
},
renderConfig: new RenderConfig
{
Type = TemplateType.Ejs,
Target = RenderTarget.Pdf
}
);
Console.WriteLine($"Document URL: {result.Output.Data.Url}");Important: You must provide either template or templateId, but not
both. Exactly one is required.
Best for: Small, quick renders where you need immediate results
Use GenerateDocumentAsync() for larger documents or when reliability is
critical. Use GenerateDocumentImmediateAsync() for small, quick renders.
StartGenerateDocumentAsync()
Lower-level method that only initializes the job. Use this if you want to implement custom polling logic.
var jobId = await client.StartGenerateDocumentAsync(
templateId: "your-template-id",
data: new Dictionary<string, object>
{
["name"] = "Jane Doe"
},
renderConfig: new RenderConfig
{
Type = TemplateType.React,
Target = RenderTarget.Pdf
}
);
Console.WriteLine($"Started job: {jobId}");Important: You must provide either template or templateId, but not
both. Exactly one is required.
Returns: Task<string> - The job ID
PollForJobCompletionAsync()
Polls for the completion of a rendering job. Use with StartGenerateDocumentAsync() for custom workflows.
var result = await client.PollForJobCompletionAsync(
jobId: jobId,
maxAttempts: 60, // default: 60
intervalMs: 500 // default: 500
);
Console.WriteLine($"Job finished: {result.Output.Data.Url}");Parameters:
jobId: The ID of the job to pollmaxAttempts: Maximum number of polling attempts (default: 60)intervalMs: Interval between attempts in milliseconds (default: 500)
Returns: Task<JobStatusResponse> - The completed job response
Template Management
SaveTemplateAsync()
Save a new template from a local ZIP file.
using System.IO;
var templateInfo = new TemplateInfo
{
Title = "My Template",
Description = "Invoice template for customers",
Type = TemplateType.React,
Categories = new[] { "invoice" },
SampleData = new Dictionary<string, object>
{
["name"] = "John Doe",
["amount"] = 1299.99
},
SourceCode = "https://github.com/yourorg/template"
};
var templateId = await client.SaveTemplateAsync(
filePath: "./path/to/template.zip",
templateInfo: templateInfo
);
Console.WriteLine($"Template saved with ID: {templateId}");Parameters:
filePath: Local file path to the ZIP filetemplateInfo: Template metadata object
Returns: Task<string> - The new template ID
SaveTemplateFromStreamAsync()
Core method for saving templates from a stream. Useful for handling uploads in web applications.
using (var fileStream = File.OpenRead("./path/to/template.zip"))
{
var templateId = await client.SaveTemplateFromStreamAsync(
stream: fileStream,
templateInfo: templateInfo
);
Console.WriteLine($"Template saved: {templateId}");
}UpdateTemplateAsync()
Update an existing template with a new version from a ZIP file.
var updateInfo = new TemplateInfo
{
Title = "My Updated Template",
Description = "Updated invoice template",
Type = TemplateType.React,
Categories = new[] { "invoice", "updated" },
SampleData = new Dictionary<string, object>
{
["name"] = "John Doe",
["amount"] = 1599.99
}
};
var contentId = await client.UpdateTemplateAsync(
templateId: "existing-template-id",
filePath: "./path/to/new-version.zip",
templateInfo: updateInfo
);
Console.WriteLine($"Template updated. New content ID: {contentId}");Returns: Task<string> - Updated template content ID
UpdateTemplateFromStreamAsync()
Update a template from a stream.
using (var fileStream = File.OpenRead("./path/to/new-version.zip"))
{
var contentId = await client.UpdateTemplateFromStreamAsync(
templateId: "existing-template-id",
stream: fileStream,
templateInfo: updateInfo
);
Console.WriteLine($"New content ID: {contentId}");
}Template Types
Pogodoc supports multiple template formats for different use cases:
| Type | Description | Best For |
|---|---|---|
React | Any frontend JS framework | Complex layouts, reusable components |
Ejs | Embedded JavaScript templates | Simple variable substitution |
Latex 🚧 | LaTeX for scientific documents | Academic papers, mathematical content |
Docx 🚧 | Microsoft Word templates | Business documents, form letters |
Xlsx 🚧 | Microsoft Excel templates | Spreadsheets, data reports |
Pptx 🚧 | Microsoft PowerPoint templates | Presentations, slides |
React Templates: Any JavaScript framework works here! Use React, Vue, Angular, Svelte, or any other framework that renders to HTML/JSX. See our JavaScript Framework Templates guide for detailed setup instructions.
🚧 Coming Soon: LaTeX, DOCX, XLSX, and PPTX template types are currently in development and will be available soon.
JavaScript Framework Templates
JavaScript framework templates require a build process and must be uploaded as ZIP files. See the complete guide: JavaScript Framework Templates
Quick example of using a React template:
// Upload your built and zipped React template
var templateId = await client.SaveTemplateAsync(
filePath: "./my-react-template.zip",
templateInfo: new TemplateInfo
{
Title = "Invoice Template",
Type = TemplateType.React,
Categories = new[] { "invoice" }
}
);
// Generate documents using the template
var result = await client.GenerateDocumentAsync(
templateId: templateId,
data: new Dictionary<string, object>
{
["customer"] = new { Name = "Jane Smith" },
["items"] = new[]
{
new { Name = "Service A", Price = 150.00 },
new { Name = "Service B", Price = 250.00 }
},
["total"] = 400.00
},
renderConfig: new RenderConfig
{
Type = TemplateType.React,
Target = RenderTarget.Pdf
}
);
Console.WriteLine($"Document URL: {result.Output.Data.Url}");EJS/HTML Template
EJS/HTML templates can be provided as inline strings:
var result = await client.GenerateDocumentAsync(
template: @"
<h1>Hello <%= name %></h1>
<p>Your order #<%= orderId %> has been confirmed.</p>
<% if (premium) { %>
<p>Thank you for being a premium member!</p>
<% } %>
",
data: new Dictionary<string, object>
{
["name"] = "John Doe",
["orderId"] = 12345,
["premium"] = true
},
renderConfig: new RenderConfig
{
Type = TemplateType.Ejs,
Target = RenderTarget.Pdf
}
);Render Targets
Generate documents in multiple output formats:
| Target | Description | Use Cases |
|---|---|---|
Pdf | PDF documents | Invoices, reports, printable documents |
Png | PNG images | Social media graphics, thumbnails |
Jpg 🚧 | JPEG images | Compressed images for web |
Html 🚧 | HTML output | Web previews, email content |
Docx 🚧 | Word documents | Editable business documents |
Xlsx 🚧 | Excel spreadsheets | Data reports, financial documents |
Pptx 🚧 | PowerPoint presentations | Slides, presentations |
🚧 Coming Soon: JPG, HTML, DOCX, XLSX, and PPTX render targets are currently in development and will be available soon.
Format Options
Customize the rendering process with format-specific options:
var result = await client.GenerateDocumentAsync(
templateId: "invoice-template",
data: invoiceData,
renderConfig: new RenderConfig
{
Type = TemplateType.React,
Target = RenderTarget.Pdf,
FormatOpts = new FormatOptions
{
Format = "A4",
WaitForSelector = ".ready",
FromPage = 1,
ToPage = 5
}
}
);Available Format Options
| Option | Type | Description |
|---|---|---|
Format | string | Page format (A3, A4, A5, Letter, Legal, Tabloid) |
WaitForSelector | string | CSS selector to wait for before rendering |
FromPage | int? | Starting page number for partial renders |
ToPage | int? | Ending page number for partial renders |
Using Saved Templates
Instead of providing template content inline, you can use templates saved in your Pogodoc dashboard:
Create a Template
Go to your Pogodoc Dashboard and create a new template. Save it and copy the template ID.
Reference the Template
var result = await client.GenerateDocumentAsync(
templateId: "your-template-id",
data: new Dictionary<string, object>
{
["name"] = "John Doe",
["amount"] = 1299.99
},
renderConfig: new RenderConfig
{
Target = RenderTarget.Pdf
}
);Best Practices
1. Use Configuration Files
Store API tokens in configuration files:
// appsettings.json
{
"Pogodoc": {
"ApiToken": "your_token_here"
}
}
// Program.cs
var token = configuration["Pogodoc:ApiToken"];
var client = new PogodocClient(token);2. Use Saved Templates
For production, use saved templates instead of inline templates:
// ✅ Good
var result = await client.GenerateDocumentAsync(
templateId: "invoice-v2",
data: data,
renderConfig: new RenderConfig { Target = RenderTarget.Pdf }
);
// ❌ Less ideal - template in code
var result = await client.GenerateDocumentAsync(
template: "<html>...</html>",
data: data,
renderConfig: new RenderConfig
{
Type = TemplateType.Html,
Target = RenderTarget.Pdf
}
);3. Error Handling
Always wrap SDK calls in try-catch blocks:
try
{
var result = await client.GenerateDocumentAsync(
templateId: "invoice",
data: data,
renderConfig: new RenderConfig { Target = RenderTarget.Pdf }
);
Console.WriteLine($"Document URL: {result.Output.Data.Url}");
}
catch (Exception ex)
{
Console.WriteLine($"Document generation failed: {ex.Message}");
// Handle error appropriately
}4. Use Dependency Injection
Inject the client as a singleton in ASP.NET Core:
// Program.cs or Startup.cs
services.AddSingleton<IPogodocClient>(sp =>
{
var token = configuration["Pogodoc:ApiToken"];
return new PogodocClient(token);
});
// Controller
public class InvoiceController : ControllerBase
{
private readonly IPogodocClient _pogodocClient;
public InvoiceController(IPogodocClient pogodocClient)
{
_pogodocClient = pogodocClient;
}
[HttpPost("generate")]
public async Task<IActionResult> GenerateInvoice([FromBody] InvoiceData data)
{
var result = await _pogodocClient.GenerateDocumentAsync(
templateId: "invoice-template",
data: data.ToDictionary(),
renderConfig: new RenderConfig { Target = RenderTarget.Pdf }
);
return Ok(new { url = result.Output.Data.Url });
}
}Examples
Invoice Generation
public async Task<string> GenerateInvoiceAsync(
PogodocClient client,
InvoiceData invoiceData)
{
var result = await client.GenerateDocumentAsync(
templateId: "invoice-template",
data: new Dictionary<string, object>
{
["invoiceNumber"] = invoiceData.Number,
["customer"] = invoiceData.Customer,
["items"] = invoiceData.Items,
["subtotal"] = invoiceData.Subtotal,
["tax"] = invoiceData.Tax,
["total"] = invoiceData.Total,
["date"] = DateTime.Now.ToString("MM/dd/yyyy")
},
renderConfig: new RenderConfig
{
Target = RenderTarget.Pdf,
FormatOpts = new FormatOptions { Format = "A4" }
}
);
return result.Output.Data.Url;
}Social Media Graphics
public async Task<string> GenerateSocialGraphicAsync(
PogodocClient client,
PostData post)
{
var result = await client.GenerateDocumentAsync(
templateId: "social-media-card",
data: new Dictionary<string, object>
{
["title"] = post.Title,
["author"] = post.Author,
["image"] = post.FeaturedImage
},
renderConfig: new RenderConfig { Target = RenderTarget.Png }
);
return result.Output.Data.Url;
}Batch Document Generation
public async Task<List<string>> GenerateMultipleDocumentsAsync(
PogodocClient client,
List<Dictionary<string, object>> dataList)
{
var urls = new List<string>();
foreach (var data in dataList)
{
try
{
var result = await client.GenerateDocumentAsync(
templateId: "report-template",
data: data,
renderConfig: new RenderConfig
{
Type = TemplateType.React,
Target = RenderTarget.Pdf
}
);
urls.Add(result.Output.Data.Url);
}
catch (Exception ex)
{
Console.WriteLine($"Failed to generate document: {ex.Message}");
continue;
}
}
return urls;
}Using with Dependency Injection
public class DocumentService : IDocumentService
{
private readonly IPogodocClient _client;
private readonly ILogger<DocumentService> _logger;
public DocumentService(
IPogodocClient client,
ILogger<DocumentService> logger)
{
_client = client;
_logger = logger;
}
public async Task<string> GenerateDocumentAsync(
string templateId,
object data)
{
try
{
var result = await _client.GenerateDocumentAsync(
templateId: templateId,
data: ConvertToDict(data),
renderConfig: new RenderConfig { Target = RenderTarget.Pdf }
);
_logger.LogInformation(
"Generated document: {Url}",
result.Output.Data.Url
);
return result.Output.Data.Url;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to generate document");
throw;
}
}
private Dictionary<string, object> ConvertToDict(object data)
{
// Convert object to dictionary using your preferred method
// (e.g., System.Text.Json, Newtonsoft.Json, reflection)
return JsonSerializer.Deserialize<Dictionary<string, object>>(
JsonSerializer.Serialize(data)
);
}
}