From 47688cac68e3558efe90de369a52df8cee82b8ac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 17:52:52 +0000 Subject: [PATCH 01/14] Initial plan From 284a78f64bd1c6e97c793dc609712958a5957442 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:01:01 +0000 Subject: [PATCH 02/14] Upgrade to .NET 10 and Aspire 13 Co-authored-by: ejsmith <282584+ejsmith@users.noreply.github.com> --- .github/workflows/build-arm64.yml | 2 +- .github/workflows/build.yaml | 4 ++-- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/elasticsearch-docker-7.yml | 2 +- .github/workflows/elasticsearch-docker-8.yml | 2 +- Dockerfile | 12 ++++++------ global.json | 2 +- src/Directory.Build.props | 2 +- .../Exceptionless.AppHost.csproj | 10 +++++----- src/Exceptionless.Core/Exceptionless.Core.csproj | 8 ++++---- src/Exceptionless.Job/Exceptionless.Job.csproj | 4 ++-- src/Exceptionless.Web/Exceptionless.Web.csproj | 6 +++--- tests/Exceptionless.Tests/Exceptionless.Tests.csproj | 6 +++--- 13 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build-arm64.yml b/.github/workflows/build-arm64.yml index d0940add98..e79cf0217b 100644 --- a/.github/workflows/build-arm64.yml +++ b/.github/workflows/build-arm64.yml @@ -25,7 +25,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Build Reason env: diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f21407f00d..dd2cd039a3 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -38,7 +38,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Version @@ -62,7 +62,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Start Services diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index f1161cee5a..f5a2e1df25 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -25,7 +25,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Start Services diff --git a/.github/workflows/elasticsearch-docker-7.yml b/.github/workflows/elasticsearch-docker-7.yml index 642b645f8c..964cba1de5 100644 --- a/.github/workflows/elasticsearch-docker-7.yml +++ b/.github/workflows/elasticsearch-docker-7.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Build Reason env: diff --git a/.github/workflows/elasticsearch-docker-8.yml b/.github/workflows/elasticsearch-docker-8.yml index af64a4217b..43f0f1dbf7 100644 --- a/.github/workflows/elasticsearch-docker-8.yml +++ b/.github/workflows/elasticsearch-docker-8.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Build Reason env: diff --git a/Dockerfile b/Dockerfile index cef8c1ef34..5b174756d2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build WORKDIR /app COPY ./*.slnx ./NuGet.Config ./ @@ -35,7 +35,7 @@ RUN dotnet publish -c Release -o out # job -FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS job +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS job WORKDIR /app COPY --from=job-publish /app/src/Exceptionless.Job/out ./ @@ -52,7 +52,7 @@ RUN dotnet publish -c Release -o out /p:SkipSpaPublish=true # api -FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS api +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS api WORKDIR /app COPY --from=api-publish /app/src/Exceptionless.Web/out ./ @@ -72,7 +72,7 @@ RUN dotnet publish -c Release -o out # app -FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS app +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS app WORKDIR /app COPY --from=app-publish /app/src/Exceptionless.Web/out ./ @@ -146,7 +146,7 @@ USER elasticsearch RUN wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh && \ chmod +x dotnet-install.sh && \ - ./dotnet-install.sh --channel 9.0 --runtime aspnetcore && \ + ./dotnet-install.sh --channel 10.0 --runtime aspnetcore && \ rm dotnet-install.sh EXPOSE 8080 9200 @@ -206,7 +206,7 @@ USER elasticsearch RUN wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh && \ chmod +x dotnet-install.sh && \ - ./dotnet-install.sh --channel 9.0 --runtime aspnetcore && \ + ./dotnet-install.sh --channel 10.0 --runtime aspnetcore && \ rm dotnet-install.sh EXPOSE 8080 9200 diff --git a/global.json b/global.json index 7f873f4e9d..1e7fdfa95f 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.100-rc*", + "version": "10.0.100", "rollForward": "latestMinor" } } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 8e86c5e5b2..0ee873a676 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,6 +1,6 @@ - net9.0 + net10.0 enable Exceptionless true diff --git a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj index 8313740fcd..0ed68c563e 100644 --- a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj +++ b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj @@ -1,16 +1,16 @@ - + Exe - net9.0 + net10.0 enable enable a9c2ddcc-e51d-4cd1-9782-96e1d74eec87 - - - + + + diff --git a/src/Exceptionless.Core/Exceptionless.Core.csproj b/src/Exceptionless.Core/Exceptionless.Core.csproj index c2328fe955..1ac3f03180 100644 --- a/src/Exceptionless.Core/Exceptionless.Core.csproj +++ b/src/Exceptionless.Core/Exceptionless.Core.csproj @@ -29,11 +29,11 @@ - - - + + + - + diff --git a/src/Exceptionless.Job/Exceptionless.Job.csproj b/src/Exceptionless.Job/Exceptionless.Job.csproj index 0434e18925..62a6b1a3f2 100644 --- a/src/Exceptionless.Job/Exceptionless.Job.csproj +++ b/src/Exceptionless.Job/Exceptionless.Job.csproj @@ -5,7 +5,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/src/Exceptionless.Web/Exceptionless.Web.csproj b/src/Exceptionless.Web/Exceptionless.Web.csproj index 6bce409dd7..15ae430b64 100644 --- a/src/Exceptionless.Web/Exceptionless.Web.csproj +++ b/src/Exceptionless.Web/Exceptionless.Web.csproj @@ -15,8 +15,8 @@ - - + + @@ -39,7 +39,7 @@ - + diff --git a/tests/Exceptionless.Tests/Exceptionless.Tests.csproj b/tests/Exceptionless.Tests/Exceptionless.Tests.csproj index aff7daf6b1..6c2d69c748 100644 --- a/tests/Exceptionless.Tests/Exceptionless.Tests.csproj +++ b/tests/Exceptionless.Tests/Exceptionless.Tests.csproj @@ -9,9 +9,9 @@ - - - + + + From 382f45bbd4127c7d4051deb7988663386b088009 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:14:25 +0000 Subject: [PATCH 03/14] Fix Aspire 13 breaking changes and build issues Co-authored-by: ejsmith <282584+ejsmith@users.noreply.github.com> --- .../Exceptionless.AppHost.csproj | 2 +- .../Extensions/ElasticsearchExtensions.cs | 3 +- .../Extensions/KibanaConfigWriterHook.cs | 36 ------------------- src/Exceptionless.AppHost/Program.cs | 8 ++--- .../Exceptionless.Insulation.csproj | 16 ++++----- .../Exceptionless.Job.csproj | 5 --- .../Exceptionless.Web.csproj | 4 --- src/Exceptionless.Web/Startup.cs | 2 +- .../Exceptionless.Tests/AppWebHostFactory.cs | 2 +- 9 files changed, 15 insertions(+), 63 deletions(-) delete mode 100644 src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs diff --git a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj index 0ed68c563e..c06307f1fa 100644 --- a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj +++ b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs index a8d8c87e7d..fb5bab6647 100644 --- a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs +++ b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs @@ -80,7 +80,8 @@ public static IResourceBuilder WithKibana(this IResourceB { containerName ??= $"{builder.Resource.Name}-kibana"; - builder.ApplicationBuilder.Services.TryAddLifecycleHook(); + // TODO: Re-enable Kibana config writer hook after updating to Aspire 13 eventing model + // builder.ApplicationBuilder.Services.AddHostedService(); var resource = new KibanaResource(containerName); var resourceBuilder = builder.ApplicationBuilder.AddResource(resource) diff --git a/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs b/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs deleted file mode 100644 index f5a338048a..0000000000 --- a/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Text; -using Aspire.Hosting.Lifecycle; - -namespace Aspire.Hosting; - -internal class KibanaConfigWriterHook : IDistributedApplicationLifecycleHook -{ - public async Task AfterEndpointsAllocatedAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken) - { - if (appModel.Resources.OfType().SingleOrDefault() is not { } kibanaResource) - return; - - var elasticsearchInstances = appModel.Resources.OfType(); - - if (!elasticsearchInstances.Any()) - return; - - var hostsVariableBuilder = new StringBuilder(); - - foreach (var elasticsearchInstance in elasticsearchInstances) - { - if (elasticsearchInstance.PrimaryEndpoint.IsAllocated) - { - var connectionString = await elasticsearchInstance.GetConnectionStringAsync(); - if (hostsVariableBuilder.Length > 0) - hostsVariableBuilder.Append(","); - hostsVariableBuilder.Append(elasticsearchInstance.PrimaryEndpoint.Scheme).Append("://").Append(elasticsearchInstance.PrimaryEndpoint.ContainerHost).Append(":").Append(elasticsearchInstance.PrimaryEndpoint.Port); - } - } - - kibanaResource.Annotations.Add(new EnvironmentCallbackAnnotation(context => - { - context.EnvironmentVariables.Add("ELASTICSEARCH_HOSTS", hostsVariableBuilder.ToString()); - })); - } -} diff --git a/src/Exceptionless.AppHost/Program.cs b/src/Exceptionless.AppHost/Program.cs index 561ae1856b..d5fa011c4d 100644 --- a/src/Exceptionless.AppHost/Program.cs +++ b/src/Exceptionless.AppHost/Program.cs @@ -48,16 +48,16 @@ .WithUrlForEndpoint("http", u => u.DisplayText = "Api") .WithHttpHealthCheck("/health"); -builder.AddNpmApp("Web", "../../src/Exceptionless.Web/ClientApp", "dev") +builder.AddJavaScriptApp("Web", "../../src/Exceptionless.Web/ClientApp", "dev") .WithReference(api) .WithEnvironment("ASPNETCORE_URLS", "http://localhost:5200") .WithUrlForEndpoint("http", u => u.DisplayText = "Web") - .WithEndpoint(port: 5173, targetPort: 5173, scheme: "http", env: "PORT", isProxied: false); + .WithHttpEndpoint(port: 5173, env: "PORT", isProxied: false); -builder.AddNpmApp("AngularWeb", "../../src/Exceptionless.Web/ClientApp.angular", "serve") +builder.AddJavaScriptApp("AngularWeb", "../../src/Exceptionless.Web/ClientApp.angular", "serve") .WithReference(api) .WithEnvironment("ASPNETCORE_URLS", "http://localhost:5200") .WithUrlForEndpoint("http", u => u.DisplayText = "Angular Web") - .WithEndpoint(port: 5100, targetPort: 5100, scheme: "http", env: "PORT", isProxied: false); + .WithHttpEndpoint(port: 5100, env: "PORT", isProxied: false); builder.Build().Run(); diff --git a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj index c690f0385f..8765950f6d 100644 --- a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj +++ b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj @@ -8,12 +8,12 @@ - - - - - - + + + + + + @@ -22,10 +22,6 @@ - - - - diff --git a/src/Exceptionless.Job/Exceptionless.Job.csproj b/src/Exceptionless.Job/Exceptionless.Job.csproj index 62a6b1a3f2..e7295e6120 100644 --- a/src/Exceptionless.Job/Exceptionless.Job.csproj +++ b/src/Exceptionless.Job/Exceptionless.Job.csproj @@ -5,7 +5,6 @@ - @@ -23,10 +22,6 @@ - - - - diff --git a/src/Exceptionless.Web/Exceptionless.Web.csproj b/src/Exceptionless.Web/Exceptionless.Web.csproj index 15ae430b64..4e870c1ae8 100644 --- a/src/Exceptionless.Web/Exceptionless.Web.csproj +++ b/src/Exceptionless.Web/Exceptionless.Web.csproj @@ -16,7 +16,6 @@ - @@ -38,9 +37,6 @@ - - - diff --git a/src/Exceptionless.Web/Startup.cs b/src/Exceptionless.Web/Startup.cs index c20655cd01..5c85ade982 100644 --- a/src/Exceptionless.Web/Startup.cs +++ b/src/Exceptionless.Web/Startup.cs @@ -53,7 +53,7 @@ public void ConfigureServices(IServiceCollection services) { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; options.RequireHeaderSymmetry = false; - options.KnownNetworks.Clear(); + options.KnownIPNetworks.Clear(); options.KnownProxies.Clear(); }); diff --git a/tests/Exceptionless.Tests/AppWebHostFactory.cs b/tests/Exceptionless.Tests/AppWebHostFactory.cs index 1c19b83822..8e60a7a067 100644 --- a/tests/Exceptionless.Tests/AppWebHostFactory.cs +++ b/tests/Exceptionless.Tests/AppWebHostFactory.cs @@ -43,7 +43,7 @@ protected override IHostBuilder CreateHostBuilder() .AddYamlFile("appsettings.yml", optional: false, reloadOnChange: false) .Build(); - return Program.CreateHostBuilder(config, Environments.Development); + return Exceptionless.Web.Program.CreateHostBuilder(config, Environments.Development); } async Task IAsyncLifetime.DisposeAsync() From f2f0f14afb64db9075d043b3ae615ebb7e7905cd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:15:38 +0000 Subject: [PATCH 04/14] Add upgrade notes documentation Co-authored-by: ejsmith <282584+ejsmith@users.noreply.github.com> --- UPGRADE_NOTES.md | 101 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 UPGRADE_NOTES.md diff --git a/UPGRADE_NOTES.md b/UPGRADE_NOTES.md new file mode 100644 index 0000000000..c74c146fbc --- /dev/null +++ b/UPGRADE_NOTES.md @@ -0,0 +1,101 @@ +# .NET 10 and Aspire 13 Upgrade Notes + +## Upgrade Summary + +Successfully upgraded from .NET 9 and Aspire 9.5 to .NET 10 and Aspire 13.0.0. + +## New Features Available + +### .NET 10 Features + +#### Performance Improvements +- **JIT Inlining Enhancements**: Improved JIT compiler inlining decisions for better runtime performance +- **Cryptography Performance**: Significant performance improvements in cryptographic operations +- **Runtime Optimizations**: Enhanced garbage collection and memory management + +#### Container Support +- **Streamlined Containerization**: Improved workflows for building and deploying containerized applications +- **Better Docker Integration**: Enhanced support for multi-stage builds and optimized images + +#### C# 14 Language Features +- **File-based Apps**: Support for single-file C# scripts that can be executed directly from the CLI +- **Enhanced Pattern Matching**: New pattern matching capabilities for cleaner code +- **Primary Constructors**: Simplified class constructor syntax + +#### API Improvements +- **Minimal APIs**: Enhanced minimal API support with better parameter binding +- **Native AOT**: Continued improvements to Native AOT compilation for faster startup and smaller deployments +- **OpenTelemetry**: Enhanced built-in telemetry and observability features + +### Aspire 13 Features + +#### Polyglot Application Platform +- **First-class JavaScript Support**: JavaScript apps are now first-class citizens alongside .NET and Python +- **AddJavaScriptApp API**: New unified API for orchestrating npm, yarn, and pnpm-based applications +- **Automatic Package Manager Detection**: Smart detection of the package manager used by JavaScript projects + +#### Enhanced Orchestration +- **Improved Vite Support**: Better hot reload, port mapping, and Dockerfile generation for Vite apps +- **Multi-stage Docker Publishing**: Optimized Dockerfile generation with Node version detection +- **Static Port Configuration**: Ability to specify static host ports for consistent callback URLs + +#### Eventing Model +- **New Eventing Infrastructure**: Modernized eventing system replacing lifecycle hooks +- **Resource-specific Events**: More granular events like `BeforeResourceStartedEvent` and `ResourceEndpointsAllocatedEvent` +- **Better Event Subscription**: Improved patterns for subscribing to application events + +#### Developer Experience +- **Enhanced Dashboard**: Improved Aspire dashboard for monitoring distributed applications +- **Better Debugging**: Enhanced debugging experience for distributed applications +- **Streamlined Local Development**: Improved local development experience with automatic port allocation + +## Breaking Changes Addressed + +### Aspire 13 Breaking Changes +1. **Package Rename**: `Aspire.Hosting.NodeJs` → `Aspire.Hosting.JavaScript` +2. **API Change**: `AddNpmApp` → `AddJavaScriptApp` with automatic package manager detection +3. **Lifecycle Hooks**: Old lifecycle hook system deprecated in favor of new eventing model +4. **Endpoint API**: `WithEndpoint` parameters changed to use `WithHttpEndpoint` + +### .NET 10 Breaking Changes +1. **ForwardedHeaders**: `KnownNetworks` property renamed to `KnownIPNetworks` +2. **Framework Packages**: Several packages (System.Net.Http, System.Text.RegularExpressions, System.Text.Encodings.Web) are now included in the framework and should be removed from project references +3. **HealthChecks**: Microsoft.Extensions.Diagnostics.HealthChecks is now included in ASP.NET Core and doesn't need explicit package reference + +## Recommendations for Future Work + +### Immediate Improvements +1. **Update KibanaConfigWriterHook**: Migrate to Aspire 13's new eventing model +2. **Leverage C# 14 Features**: Consider using primary constructors and enhanced pattern matching in new code +3. **OpenTelemetry Integration**: Take advantage of enhanced built-in telemetry features + +### Performance Optimizations +1. **Review Cryptography Usage**: Update crypto operations to leverage .NET 10 performance improvements +2. **Container Optimization**: Review Dockerfiles to take advantage of new multi-stage build optimizations +3. **JIT Compiler Benefits**: Profile hot paths to measure JIT inlining improvements + +### Developer Experience +1. **Aspire Dashboard**: Utilize the enhanced dashboard for better observability during development +2. **JavaScript Integration**: Consider migrating to AddJavaScriptApp pattern for better package manager support +3. **Static Ports**: Use static port configuration for better development consistency + +## Migration Notes + +### Completed +- ✅ All projects targeting net10.0 +- ✅ Aspire packages updated to 13.0.0 +- ✅ Microsoft.Extensions packages updated to 10.0.0 +- ✅ Docker images updated to .NET 10 +- ✅ GitHub Actions workflows updated to .NET 10 +- ✅ Deprecated APIs replaced + +### Pending +- ⏳ KibanaConfigWriterHook eventing model update (temporarily disabled with TODO) +- ⏳ Full testing of Aspire 13 JavaScript integration +- ⏳ Performance profiling to measure .NET 10 improvements + +## References +- [.NET 10 What's New](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/overview) +- [Aspire 13 What's New](https://aspire.dev/whats-new/aspire-13/) +- [Aspire 13 Breaking Changes](https://learn.microsoft.com/en-us/dotnet/aspire/compatibility/13.0/) +- [C# 14 Language Features](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14) From a66d92976ccf78d4020f29cbc2eb2b0de74fa281 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:29:02 +0000 Subject: [PATCH 05/14] Fix Kibana configuration, update VSCode paths, and remove upgrade notes Co-authored-by: niemyjski <1020579+niemyjski@users.noreply.github.com> --- .vscode/launch.json | 6 +- UPGRADE_NOTES.md | 101 ------------------ .../Extensions/ElasticsearchExtensions.cs | 6 +- .../Extensions/KibanaConfigWriterHook.cs | 42 ++++++++ 4 files changed, 48 insertions(+), 107 deletions(-) delete mode 100644 UPGRADE_NOTES.md create mode 100644 src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs diff --git a/.vscode/launch.json b/.vscode/launch.json index dd21f34004..2253f36821 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/src/Exceptionless.AppHost/bin/Debug/net9.0/Exceptionless.AppHost.dll", + "program": "${workspaceFolder}/src/Exceptionless.AppHost/bin/Debug/net10.0/Exceptionless.AppHost.dll", "args": [], "cwd": "${workspaceFolder}/src/Exceptionless.AppHost", "stopAtEntry": false, @@ -23,7 +23,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/src/Exceptionless.Web/bin/Debug/net9.0/Exceptionless.Web.dll", + "program": "${workspaceFolder}/src/Exceptionless.Web/bin/Debug/net10.0/Exceptionless.Web.dll", "args": [], "cwd": "${workspaceFolder}/src/Exceptionless.Web", "stopAtEntry": false, @@ -40,7 +40,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/src/Exceptionless.Job/bin/Debug/net9.0/Exceptionless.Job.dll", + "program": "${workspaceFolder}/src/Exceptionless.Job/bin/Debug/net10.0/Exceptionless.Job.dll", "args": [], "cwd": "${workspaceFolder}", "stopAtEntry": false, diff --git a/UPGRADE_NOTES.md b/UPGRADE_NOTES.md deleted file mode 100644 index c74c146fbc..0000000000 --- a/UPGRADE_NOTES.md +++ /dev/null @@ -1,101 +0,0 @@ -# .NET 10 and Aspire 13 Upgrade Notes - -## Upgrade Summary - -Successfully upgraded from .NET 9 and Aspire 9.5 to .NET 10 and Aspire 13.0.0. - -## New Features Available - -### .NET 10 Features - -#### Performance Improvements -- **JIT Inlining Enhancements**: Improved JIT compiler inlining decisions for better runtime performance -- **Cryptography Performance**: Significant performance improvements in cryptographic operations -- **Runtime Optimizations**: Enhanced garbage collection and memory management - -#### Container Support -- **Streamlined Containerization**: Improved workflows for building and deploying containerized applications -- **Better Docker Integration**: Enhanced support for multi-stage builds and optimized images - -#### C# 14 Language Features -- **File-based Apps**: Support for single-file C# scripts that can be executed directly from the CLI -- **Enhanced Pattern Matching**: New pattern matching capabilities for cleaner code -- **Primary Constructors**: Simplified class constructor syntax - -#### API Improvements -- **Minimal APIs**: Enhanced minimal API support with better parameter binding -- **Native AOT**: Continued improvements to Native AOT compilation for faster startup and smaller deployments -- **OpenTelemetry**: Enhanced built-in telemetry and observability features - -### Aspire 13 Features - -#### Polyglot Application Platform -- **First-class JavaScript Support**: JavaScript apps are now first-class citizens alongside .NET and Python -- **AddJavaScriptApp API**: New unified API for orchestrating npm, yarn, and pnpm-based applications -- **Automatic Package Manager Detection**: Smart detection of the package manager used by JavaScript projects - -#### Enhanced Orchestration -- **Improved Vite Support**: Better hot reload, port mapping, and Dockerfile generation for Vite apps -- **Multi-stage Docker Publishing**: Optimized Dockerfile generation with Node version detection -- **Static Port Configuration**: Ability to specify static host ports for consistent callback URLs - -#### Eventing Model -- **New Eventing Infrastructure**: Modernized eventing system replacing lifecycle hooks -- **Resource-specific Events**: More granular events like `BeforeResourceStartedEvent` and `ResourceEndpointsAllocatedEvent` -- **Better Event Subscription**: Improved patterns for subscribing to application events - -#### Developer Experience -- **Enhanced Dashboard**: Improved Aspire dashboard for monitoring distributed applications -- **Better Debugging**: Enhanced debugging experience for distributed applications -- **Streamlined Local Development**: Improved local development experience with automatic port allocation - -## Breaking Changes Addressed - -### Aspire 13 Breaking Changes -1. **Package Rename**: `Aspire.Hosting.NodeJs` → `Aspire.Hosting.JavaScript` -2. **API Change**: `AddNpmApp` → `AddJavaScriptApp` with automatic package manager detection -3. **Lifecycle Hooks**: Old lifecycle hook system deprecated in favor of new eventing model -4. **Endpoint API**: `WithEndpoint` parameters changed to use `WithHttpEndpoint` - -### .NET 10 Breaking Changes -1. **ForwardedHeaders**: `KnownNetworks` property renamed to `KnownIPNetworks` -2. **Framework Packages**: Several packages (System.Net.Http, System.Text.RegularExpressions, System.Text.Encodings.Web) are now included in the framework and should be removed from project references -3. **HealthChecks**: Microsoft.Extensions.Diagnostics.HealthChecks is now included in ASP.NET Core and doesn't need explicit package reference - -## Recommendations for Future Work - -### Immediate Improvements -1. **Update KibanaConfigWriterHook**: Migrate to Aspire 13's new eventing model -2. **Leverage C# 14 Features**: Consider using primary constructors and enhanced pattern matching in new code -3. **OpenTelemetry Integration**: Take advantage of enhanced built-in telemetry features - -### Performance Optimizations -1. **Review Cryptography Usage**: Update crypto operations to leverage .NET 10 performance improvements -2. **Container Optimization**: Review Dockerfiles to take advantage of new multi-stage build optimizations -3. **JIT Compiler Benefits**: Profile hot paths to measure JIT inlining improvements - -### Developer Experience -1. **Aspire Dashboard**: Utilize the enhanced dashboard for better observability during development -2. **JavaScript Integration**: Consider migrating to AddJavaScriptApp pattern for better package manager support -3. **Static Ports**: Use static port configuration for better development consistency - -## Migration Notes - -### Completed -- ✅ All projects targeting net10.0 -- ✅ Aspire packages updated to 13.0.0 -- ✅ Microsoft.Extensions packages updated to 10.0.0 -- ✅ Docker images updated to .NET 10 -- ✅ GitHub Actions workflows updated to .NET 10 -- ✅ Deprecated APIs replaced - -### Pending -- ⏳ KibanaConfigWriterHook eventing model update (temporarily disabled with TODO) -- ⏳ Full testing of Aspire 13 JavaScript integration -- ⏳ Performance profiling to measure .NET 10 improvements - -## References -- [.NET 10 What's New](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/overview) -- [Aspire 13 What's New](https://aspire.dev/whats-new/aspire-13/) -- [Aspire 13 Breaking Changes](https://learn.microsoft.com/en-us/dotnet/aspire/compatibility/13.0/) -- [C# 14 Language Features](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14) diff --git a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs index fb5bab6647..16f1f54ed5 100644 --- a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs +++ b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs @@ -80,8 +80,7 @@ public static IResourceBuilder WithKibana(this IResourceB { containerName ??= $"{builder.Resource.Name}-kibana"; - // TODO: Re-enable Kibana config writer hook after updating to Aspire 13 eventing model - // builder.ApplicationBuilder.Services.AddHostedService(); + var elasticsearchResources = builder.ApplicationBuilder.Resources.OfType(); var resource = new KibanaResource(containerName); var resourceBuilder = builder.ApplicationBuilder.AddResource(resource) @@ -90,7 +89,8 @@ public static IResourceBuilder WithKibana(this IResourceB .WithHttpEndpoint(targetPort: KibanaPort, name: containerName) .WithUrlForEndpoint(containerName, u => u.DisplayText = "Kibana") .WithEnvironment("xpack.security.enabled", "false") - .ExcludeFromManifest(); + .ExcludeFromManifest() + .ConfigureElasticsearchHosts(elasticsearchResources); configureContainer?.Invoke(resourceBuilder); diff --git a/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs b/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs new file mode 100644 index 0000000000..37f7e751c9 --- /dev/null +++ b/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs @@ -0,0 +1,42 @@ +using System.Text; +using Aspire.Hosting.ApplicationModel; + +namespace Aspire.Hosting; + +internal static class KibanaConfigWriterExtensions +{ + public static IResourceBuilder ConfigureElasticsearchHosts( + this IResourceBuilder builder, + IEnumerable elasticsearchResources) + { + builder.WithAnnotation(new EnvironmentCallbackAnnotation(async context => + { + var hostsVariableBuilder = new StringBuilder(); + + foreach (var elasticsearchInstance in elasticsearchResources) + { + if (elasticsearchInstance.PrimaryEndpoint.IsAllocated) + { + if (hostsVariableBuilder.Length > 0) + hostsVariableBuilder.Append(","); + + var endpoint = elasticsearchInstance.PrimaryEndpoint; + hostsVariableBuilder.Append(endpoint.Scheme) + .Append("://") + .Append(endpoint.Host) + .Append(":") + .Append(endpoint.Port); + } + } + + if (hostsVariableBuilder.Length > 0) + { + context.EnvironmentVariables["ELASTICSEARCH_HOSTS"] = hostsVariableBuilder.ToString(); + } + + await Task.CompletedTask; + })); + + return builder; + } +} From c19bb00f72f0ea0f423e6772b7d65b7b2da750a3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 19:09:28 +0000 Subject: [PATCH 06/14] Fix Aspire SDK version and add TODO for Kibana lifecycle hook migration Co-authored-by: niemyjski <1020579+niemyjski@users.noreply.github.com> --- .../Exceptionless.AppHost.csproj | 2 +- .../Extensions/ElasticsearchExtensions.cs | 8 +-- .../Extensions/KibanaConfigWriterHook.cs | 52 +++++++++---------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj index c06307f1fa..4b6abfe247 100644 --- a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj +++ b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj @@ -1,5 +1,5 @@ - + Exe net10.0 diff --git a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs index 16f1f54ed5..74f7d7352a 100644 --- a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs +++ b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs @@ -80,7 +80,10 @@ public static IResourceBuilder WithKibana(this IResourceB { containerName ??= $"{builder.Resource.Name}-kibana"; - var elasticsearchResources = builder.ApplicationBuilder.Resources.OfType(); + // TODO: Update KibanaConfigWriterHook to use Aspire 13 eventing model (IDistributedApplicationEventingSubscriber) + // The IDistributedApplicationLifecycleHook interface is obsolete in Aspire 13. + // See: https://learn.microsoft.com/en-us/dotnet/aspire/compatibility/13.0/ + // builder.ApplicationBuilder.Services.TryAddLifecycleHook(); var resource = new KibanaResource(containerName); var resourceBuilder = builder.ApplicationBuilder.AddResource(resource) @@ -89,8 +92,7 @@ public static IResourceBuilder WithKibana(this IResourceB .WithHttpEndpoint(targetPort: KibanaPort, name: containerName) .WithUrlForEndpoint(containerName, u => u.DisplayText = "Kibana") .WithEnvironment("xpack.security.enabled", "false") - .ExcludeFromManifest() - .ConfigureElasticsearchHosts(elasticsearchResources); + .ExcludeFromManifest(); configureContainer?.Invoke(resourceBuilder); diff --git a/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs b/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs index 37f7e751c9..c06f3bcb88 100644 --- a/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs +++ b/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs @@ -1,42 +1,38 @@ +#if FALSE // TODO: Re-enable and update to Aspire 13 eventing model (IDistributedApplicationEventingSubscriber) using System.Text; -using Aspire.Hosting.ApplicationModel; +using Aspire.Hosting.Lifecycle; namespace Aspire.Hosting; -internal static class KibanaConfigWriterExtensions +internal class KibanaConfigWriterHook : IDistributedApplicationLifecycleHook { - public static IResourceBuilder ConfigureElasticsearchHosts( - this IResourceBuilder builder, - IEnumerable elasticsearchResources) + public async Task AfterEndpointsAllocatedAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken) { - builder.WithAnnotation(new EnvironmentCallbackAnnotation(async context => - { - var hostsVariableBuilder = new StringBuilder(); + if (appModel.Resources.OfType().SingleOrDefault() is not { } kibanaResource) + return; - foreach (var elasticsearchInstance in elasticsearchResources) - { - if (elasticsearchInstance.PrimaryEndpoint.IsAllocated) - { - if (hostsVariableBuilder.Length > 0) - hostsVariableBuilder.Append(","); - - var endpoint = elasticsearchInstance.PrimaryEndpoint; - hostsVariableBuilder.Append(endpoint.Scheme) - .Append("://") - .Append(endpoint.Host) - .Append(":") - .Append(endpoint.Port); - } - } + var elasticsearchInstances = appModel.Resources.OfType(); + + if (!elasticsearchInstances.Any()) + return; - if (hostsVariableBuilder.Length > 0) + var hostsVariableBuilder = new StringBuilder(); + + foreach (var elasticsearchInstance in elasticsearchInstances) + { + if (elasticsearchInstance.PrimaryEndpoint.IsAllocated) { - context.EnvironmentVariables["ELASTICSEARCH_HOSTS"] = hostsVariableBuilder.ToString(); + var connectionString = await elasticsearchInstance.GetConnectionStringAsync(); + if (hostsVariableBuilder.Length > 0) + hostsVariableBuilder.Append(","); + hostsVariableBuilder.Append(elasticsearchInstance.PrimaryEndpoint.Scheme).Append("://").Append(elasticsearchInstance.PrimaryEndpoint.Host).Append(":").Append(elasticsearchInstance.PrimaryEndpoint.Port); } + } - await Task.CompletedTask; + kibanaResource.Annotations.Add(new EnvironmentCallbackAnnotation(context => + { + context.EnvironmentVariables.Add("ELASTICSEARCH_HOSTS", hostsVariableBuilder.ToString()); })); - - return builder; } } +#endif From 51cc6ca491d7f82839df70e58a48a2addf1d58ab Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Thu, 13 Nov 2025 20:00:12 +1300 Subject: [PATCH 07/14] PR Feedback --- .vscode/extensions.json | 3 +- .vscode/launch.json | 225 +++++++++--------- .../Exceptionless.AppHost.csproj | 6 +- .../Extensions/ElasticsearchExtensions.cs | 5 +- .../Extensions/KibanaConfigWriterHook.cs | 60 +++-- src/Exceptionless.AppHost/Program.cs | 12 +- .../Exceptionless.Tests/AppWebHostFactory.cs | 2 +- 7 files changed, 156 insertions(+), 157 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index c30d935b28..a8d2e79ec3 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -4,11 +4,12 @@ "streetsidesoftware.code-spell-checker", "tintoy.msbuild-project-tools", "humao.rest-client", - "ms-kubernetes-tools.vscode-kubernetes-tools", "svelte.svelte-vscode", "bradlc.vscode-tailwindcss", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", + "microsoft-aspire.aspire-vscode", + "ms-kubernetes-tools.vscode-kubernetes-tools", "ms-playwright.playwright", "selemondev.vscode-shadcn-svelte", "vitest.explorer" diff --git a/.vscode/launch.json b/.vscode/launch.json index 2253f36821..90a926b9f8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,120 +1,109 @@ { - "version": "0.2.0", - "configurations": [ - { - "name": "Aspire", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/src/Exceptionless.AppHost/bin/Debug/net10.0/Exceptionless.AppHost.dll", - "args": [], - "cwd": "${workspaceFolder}/src/Exceptionless.AppHost", - "stopAtEntry": false, - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, - "env": { - "AppMode": "Development" - } - }, - { - "name": "Web", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/src/Exceptionless.Web/bin/Debug/net10.0/Exceptionless.Web.dll", - "args": [], - "cwd": "${workspaceFolder}/src/Exceptionless.Web", - "stopAtEntry": false, - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, - "env": { - "AppMode": "Development" - } - }, - { - "name": "Job", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/src/Exceptionless.Job/bin/Debug/net10.0/Exceptionless.Job.dll", - "args": [], - "cwd": "${workspaceFolder}", - "stopAtEntry": false, - "console": "internalConsole", - "env": { - "AppMode": "Development" - } - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach" - }, - { - "name": "frontend: Attach to Chrome", - "port": 9222, - "request": "attach", - "type": "chrome", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp" - }, - { - "name": "frontend: Attach to Edge", - "port": 9222, - "request": "attach", - "type": "msedge", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp" - }, - { - "type": "msedge", - "request": "launch", - "name": "frontend: Web (Edge)", - "url": "http://localhost:5173/next", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run dev" - }, - { - "type": "msedge", - "request": "launch", - "name": "frontend: Web Dev Api (Edge)", - "url": "http://localhost:5173/next", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run dev:api" - }, - { - "type": "msedge", - "request": "launch", - "name": "frontend: Storybook (Edge)", - "url": "http://localhost:6006", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run storybook" - }, - { - "type": "chrome", - "request": "launch", - "name": "frontend: Web (Chrome)", - "url": "http://localhost:5173/next", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run dev" - }, - { - "type": "chrome", - "request": "launch", - "name": "frontend: Web Dev Api (Chrome)", - "url": "http://localhost:5173/next", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run dev:api" - }, - { - "type": "chrome", - "request": "launch", - "name": "frontend: Storybook (Chrome)", - "url": "http://localhost:6006", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run storybook" - } - ] + "version": "0.2.0", + "configurations": [ + { + "type": "aspire", + "request": "launch", + "name": "Aspire", + "program": "${workspaceFolder}/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj" + }, + { + "name": "Web", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/src/Exceptionless.Web/bin/Debug/net10.0/Exceptionless.Web.dll", + "args": [], + "cwd": "${workspaceFolder}/src/Exceptionless.Web", + "stopAtEntry": false, + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)" + }, + "env": { + "AppMode": "Development" + } + }, + { + "name": "Job", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/src/Exceptionless.Job/bin/Debug/net10.0/Exceptionless.Job.dll", + "args": [], + "cwd": "${workspaceFolder}", + "stopAtEntry": false, + "console": "internalConsole", + "env": { + "AppMode": "Development" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + }, + { + "name": "frontend: Attach to Chrome", + "port": 9222, + "request": "attach", + "type": "chrome", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp" + }, + { + "name": "frontend: Attach to Edge", + "port": 9222, + "request": "attach", + "type": "msedge", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp" + }, + { + "type": "msedge", + "request": "launch", + "name": "frontend: Web (Edge)", + "url": "http://localhost:5173/next", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run dev" + }, + { + "type": "msedge", + "request": "launch", + "name": "frontend: Web Dev Api (Edge)", + "url": "http://localhost:5173/next", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run dev:api" + }, + { + "type": "msedge", + "request": "launch", + "name": "frontend: Storybook (Edge)", + "url": "http://localhost:6006", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run storybook" + }, + { + "type": "chrome", + "request": "launch", + "name": "frontend: Web (Chrome)", + "url": "http://localhost:5173/next", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run dev" + }, + { + "type": "chrome", + "request": "launch", + "name": "frontend: Web Dev Api (Chrome)", + "url": "http://localhost:5173/next", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run dev:api" + }, + { + "type": "chrome", + "request": "launch", + "name": "frontend: Storybook (Chrome)", + "url": "http://localhost:6006", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run storybook" + } + ] } diff --git a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj index 4b6abfe247..e3f7cfe7e8 100644 --- a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj +++ b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj @@ -1,5 +1,4 @@ - - + Exe net10.0 @@ -8,7 +7,6 @@ a9c2ddcc-e51d-4cd1-9782-96e1d74eec87 - @@ -20,4 +18,4 @@ - \ No newline at end of file + diff --git a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs index 74f7d7352a..59aa12a2a7 100644 --- a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs +++ b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs @@ -80,10 +80,7 @@ public static IResourceBuilder WithKibana(this IResourceB { containerName ??= $"{builder.Resource.Name}-kibana"; - // TODO: Update KibanaConfigWriterHook to use Aspire 13 eventing model (IDistributedApplicationEventingSubscriber) - // The IDistributedApplicationLifecycleHook interface is obsolete in Aspire 13. - // See: https://learn.microsoft.com/en-us/dotnet/aspire/compatibility/13.0/ - // builder.ApplicationBuilder.Services.TryAddLifecycleHook(); + builder.ApplicationBuilder.Services.TryAddEventingSubscriber(); var resource = new KibanaResource(containerName); var resourceBuilder = builder.ApplicationBuilder.AddResource(resource) diff --git a/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs b/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs index c06f3bcb88..005504ad74 100644 --- a/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs +++ b/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs @@ -1,38 +1,52 @@ -#if FALSE // TODO: Re-enable and update to Aspire 13 eventing model (IDistributedApplicationEventingSubscriber) -using System.Text; +using System.Text; +using Aspire.Hosting.Eventing; using Aspire.Hosting.Lifecycle; namespace Aspire.Hosting; -internal class KibanaConfigWriterHook : IDistributedApplicationLifecycleHook +internal class KibanaConfigWriterHook : IDistributedApplicationEventingSubscriber { - public async Task AfterEndpointsAllocatedAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken) + public Task SubscribeAsync(IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext executionContext, CancellationToken cancellationToken) { - if (appModel.Resources.OfType().SingleOrDefault() is not { } kibanaResource) - return; + var elasticsearchResources = new List(); - var elasticsearchInstances = appModel.Resources.OfType(); - - if (!elasticsearchInstances.Any()) - return; + eventing.Subscribe((evt, _) => + { + switch (evt.Resource) + { + case ElasticsearchResource elastic: + elasticsearchResources.Add(elastic); + break; + } - var hostsVariableBuilder = new StringBuilder(); + return Task.CompletedTask; + }); - foreach (var elasticsearchInstance in elasticsearchInstances) + eventing.Subscribe((evt, _) => { - if (elasticsearchInstance.PrimaryEndpoint.IsAllocated) + if (evt.Resource is not KibanaResource kibanaResource) + return Task.CompletedTask; + + if (elasticsearchResources.Count is 0) + return Task.CompletedTask; + + var sb = new StringBuilder(); + foreach (var resource in elasticsearchResources.Where(elasticsearchInstance => elasticsearchInstance.PrimaryEndpoint.IsAllocated)) { - var connectionString = await elasticsearchInstance.GetConnectionStringAsync(); - if (hostsVariableBuilder.Length > 0) - hostsVariableBuilder.Append(","); - hostsVariableBuilder.Append(elasticsearchInstance.PrimaryEndpoint.Scheme).Append("://").Append(elasticsearchInstance.PrimaryEndpoint.Host).Append(":").Append(elasticsearchInstance.PrimaryEndpoint.Port); + if (sb.Length > 0) + sb.Append(','); + + sb.Append($"{resource.PrimaryEndpoint.Scheme}://{resource.PrimaryEndpoint.Host}:{resource.PrimaryEndpoint.Port}"); } - } - kibanaResource.Annotations.Add(new EnvironmentCallbackAnnotation(context => - { - context.EnvironmentVariables.Add("ELASTICSEARCH_HOSTS", hostsVariableBuilder.ToString()); - })); + kibanaResource.Annotations.Add(new EnvironmentCallbackAnnotation(context => + { + context.EnvironmentVariables.Add("ELASTICSEARCH_HOSTS", sb.ToString()); + })); + + return Task.CompletedTask; + }); + + return Task.CompletedTask; } } -#endif diff --git a/src/Exceptionless.AppHost/Program.cs b/src/Exceptionless.AppHost/Program.cs index d5fa011c4d..e12fed4043 100644 --- a/src/Exceptionless.AppHost/Program.cs +++ b/src/Exceptionless.AppHost/Program.cs @@ -21,7 +21,7 @@ .WithImageTag("v1.27.10") .WithLifetime(ContainerLifetime.Persistent) .WithContainerName("Exceptionless-Mail") - .WithEndpoint(8025, 8025, "http") + .WithHttpEndpoint(8025, 8025, "http") .WithUrlForEndpoint("http", u => u.DisplayText = "Mail") .WithEndpoint(1025, 1025); @@ -48,16 +48,16 @@ .WithUrlForEndpoint("http", u => u.DisplayText = "Api") .WithHttpHealthCheck("/health"); -builder.AddJavaScriptApp("Web", "../../src/Exceptionless.Web/ClientApp", "dev") +builder.AddViteApp("Web", "../../src/Exceptionless.Web/ClientApp") .WithReference(api) .WithEnvironment("ASPNETCORE_URLS", "http://localhost:5200") - .WithUrlForEndpoint("http", u => u.DisplayText = "Web") - .WithHttpEndpoint(port: 5173, env: "PORT", isProxied: false); + .WithUrlForEndpoint("Web", u => u.DisplayText = "Web") + .WithHttpEndpoint(port: 5173, targetPort: 5173, name: "Web", env: "PORT", isProxied: false); builder.AddJavaScriptApp("AngularWeb", "../../src/Exceptionless.Web/ClientApp.angular", "serve") .WithReference(api) .WithEnvironment("ASPNETCORE_URLS", "http://localhost:5200") - .WithUrlForEndpoint("http", u => u.DisplayText = "Angular Web") - .WithHttpEndpoint(port: 5100, env: "PORT", isProxied: false); + .WithUrlForEndpoint("AngularWeb", u => u.DisplayText = "Angular Web") + .WithHttpEndpoint(port: 5100, targetPort: 5100, name: "AngularWeb", env: "PORT", isProxied: false); builder.Build().Run(); diff --git a/tests/Exceptionless.Tests/AppWebHostFactory.cs b/tests/Exceptionless.Tests/AppWebHostFactory.cs index 8e60a7a067..dda75b7c8e 100644 --- a/tests/Exceptionless.Tests/AppWebHostFactory.cs +++ b/tests/Exceptionless.Tests/AppWebHostFactory.cs @@ -43,7 +43,7 @@ protected override IHostBuilder CreateHostBuilder() .AddYamlFile("appsettings.yml", optional: false, reloadOnChange: false) .Build(); - return Exceptionless.Web.Program.CreateHostBuilder(config, Environments.Development); + return Web.Program.CreateHostBuilder(config, Environments.Development); } async Task IAsyncLifetime.DisposeAsync() From 26cab69e1ceb6858b32bcb031027dcd71433e2a9 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Thu, 13 Nov 2025 20:30:57 +1300 Subject: [PATCH 08/14] Updates package dependencies Updates various package dependencies across multiple projects. This includes updates to FluentValidation, Serilog.Sinks.Console, OpenTelemetry, Swashbuckle.AspNetCore.Newtonsoft, FluentRest.NewtonsoftJson, and Microsoft.NET.Test.Sdk. Also adds System.Net.Http and System.Text.RegularExpressions to resolve vulnerability warnings related to transitive dependencies. --- src/Exceptionless.Core/Exceptionless.Core.csproj | 2 +- .../Exceptionless.Insulation.csproj | 6 +++++- src/Exceptionless.Job/Exceptionless.Job.csproj | 12 ++++++------ src/Exceptionless.Web/Exceptionless.Web.csproj | 14 +++++++------- .../Exceptionless.Tests/Exceptionless.Tests.csproj | 4 ++-- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/Exceptionless.Core/Exceptionless.Core.csproj b/src/Exceptionless.Core/Exceptionless.Core.csproj index 1ac3f03180..e42893e952 100644 --- a/src/Exceptionless.Core/Exceptionless.Core.csproj +++ b/src/Exceptionless.Core/Exceptionless.Core.csproj @@ -22,7 +22,7 @@ - + diff --git a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj index 8765950f6d..9ee1cf456e 100644 --- a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj +++ b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj @@ -18,10 +18,14 @@ - + + + + + diff --git a/src/Exceptionless.Job/Exceptionless.Job.csproj b/src/Exceptionless.Job/Exceptionless.Job.csproj index e7295e6120..244ad58392 100644 --- a/src/Exceptionless.Job/Exceptionless.Job.csproj +++ b/src/Exceptionless.Job/Exceptionless.Job.csproj @@ -10,12 +10,12 @@ - - - - - - + + + + + + diff --git a/src/Exceptionless.Web/Exceptionless.Web.csproj b/src/Exceptionless.Web/Exceptionless.Web.csproj index 4e870c1ae8..bce5f5c8ea 100644 --- a/src/Exceptionless.Web/Exceptionless.Web.csproj +++ b/src/Exceptionless.Web/Exceptionless.Web.csproj @@ -24,17 +24,17 @@ - - - - - - + + + + + + - + diff --git a/tests/Exceptionless.Tests/Exceptionless.Tests.csproj b/tests/Exceptionless.Tests/Exceptionless.Tests.csproj index 6c2d69c748..0305fe17d8 100644 --- a/tests/Exceptionless.Tests/Exceptionless.Tests.csproj +++ b/tests/Exceptionless.Tests/Exceptionless.Tests.csproj @@ -7,12 +7,12 @@ - + - + From 8c68fbdb9f220a81d38ffe2094db1c3e3d99367e Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Thu, 13 Nov 2025 20:50:48 +1300 Subject: [PATCH 09/14] WIP - Upgrade swashbuckle --- .../Exceptionless.Web.csproj | 2 +- src/Exceptionless.Web/Startup.cs | 30 +++++-------------- .../Utility/RequestBodyOperationFilter.cs | 19 ++++++++---- 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/Exceptionless.Web/Exceptionless.Web.csproj b/src/Exceptionless.Web/Exceptionless.Web.csproj index bce5f5c8ea..af79fd1463 100644 --- a/src/Exceptionless.Web/Exceptionless.Web.csproj +++ b/src/Exceptionless.Web/Exceptionless.Web.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Exceptionless.Web/Startup.cs b/src/Exceptionless.Web/Startup.cs index 5c85ade982..41885463eb 100644 --- a/src/Exceptionless.Web/Startup.cs +++ b/src/Exceptionless.Web/Startup.cs @@ -22,7 +22,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.NewtonsoftJson; using Microsoft.Net.Http.Headers; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using Newtonsoft.Json; using Serilog; using Serilog.Events; @@ -135,26 +135,12 @@ public void ConfigureServices(IServiceCollection services) Type = SecuritySchemeType.ApiKey }); - c.AddSecurityRequirement(new OpenApiSecurityRequirement { - { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Basic" } - }, - Array.Empty() - }, - { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } - }, - Array.Empty() - }, - { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Token" } - }, - Array.Empty() - } - }); + c.AddSecurityRequirement(document => new OpenApiSecurityRequirement + { + { new OpenApiSecuritySchemeReference("Basic", document), [] }, + { new OpenApiSecuritySchemeReference("Bearer", document), [] }, + { new OpenApiSecuritySchemeReference("Token", document), [] } + }); string xmlDocPath = Path.Combine(AppContext.BaseDirectory, "Exceptionless.Web.xml"); if (File.Exists(xmlDocPath)) @@ -236,7 +222,7 @@ ApplicationException applicationException when applicationException.Message.Cont Predicate = hcr => hcr.Tags.Contains("Critical") || (options.RunJobsInProcess && hcr.Tags.Contains("AllJobs")) }); - var readyTags = new List { "Critical" }; + List readyTags = ["Critical"]; if (!options.EventSubmissionDisabled) readyTags.Add("Storage"); app.UseReadyHealthChecks(readyTags.ToArray()); diff --git a/src/Exceptionless.Web/Utility/RequestBodyOperationFilter.cs b/src/Exceptionless.Web/Utility/RequestBodyOperationFilter.cs index 1c73e36bb9..3298480620 100644 --- a/src/Exceptionless.Web/Utility/RequestBodyOperationFilter.cs +++ b/src/Exceptionless.Web/Utility/RequestBodyOperationFilter.cs @@ -1,9 +1,11 @@ +using System.Text.Json.Nodes; using Microsoft.AspNetCore.Mvc; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using Swashbuckle.AspNetCore.SwaggerGen; -public class RequestBodyContentAttribute : Attribute { } +public class RequestBodyContentAttribute : Attribute +{ +} public class RequestBodyOperationFilter : IOperationFilter { @@ -17,12 +19,17 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) if (consumesAttribute is null) return; - operation.RequestBody = new OpenApiRequestBody { Required = true }; + operation.RequestBody = new OpenApiRequestBody + { + Required = true, + Content = new Dictionary() + }; + foreach (string contentType in consumesAttribute.ContentTypes) { - operation.RequestBody.Content.Add(contentType, new OpenApiMediaType + operation.RequestBody.Content!.Add(contentType, new OpenApiMediaType { - Schema = new OpenApiSchema { Type = "string", Example = new OpenApiString(String.Empty) } + Schema = new OpenApiSchema { Type = JsonSchemaType.String, Example = JsonValue.Create(String.Empty) } }); } } From a5f35524c02b2340e5ea21ff34d4baa544d9b3a7 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Thu, 4 Dec 2025 21:05:37 -0600 Subject: [PATCH 10/14] Adds event serialization test Adds a test case to verify event serialization, including environment and request information, ensuring correct snake_case serialization of the JSON output. Also adds OpenAPI spec. --- .../Data/event-serialization-input.json | 29 + .../Data/event-serialization-response.json | 48 + .../Controllers/Data/swagger.json | 7800 +++++++++++++++++ .../Controllers/EventControllerTests.cs | 37 + .../Controllers/OpenApiControllerTests.cs | 27 + 5 files changed, 7941 insertions(+) create mode 100644 tests/Exceptionless.Tests/Controllers/Data/event-serialization-input.json create mode 100644 tests/Exceptionless.Tests/Controllers/Data/event-serialization-response.json create mode 100644 tests/Exceptionless.Tests/Controllers/Data/swagger.json create mode 100644 tests/Exceptionless.Tests/Controllers/OpenApiControllerTests.cs diff --git a/tests/Exceptionless.Tests/Controllers/Data/event-serialization-input.json b/tests/Exceptionless.Tests/Controllers/Data/event-serialization-input.json new file mode 100644 index 0000000000..a9bfac892d --- /dev/null +++ b/tests/Exceptionless.Tests/Controllers/Data/event-serialization-input.json @@ -0,0 +1,29 @@ +{ + "type": "error", + "message": "Test error for serialization verification", + "tags": ["test", "serialization"], + "@environment": { + "o_s_name": "Windows 11", + "o_s_version": "10.0.22621", + "ip_address": "192.168.1.100", + "machine_name": "TEST-MACHINE", + "runtime_version": ".NET 8.0.1", + "processor_count": 8, + "total_physical_memory": 17179869184, + "available_physical_memory": 8589934592, + "process_name": "TestApp", + "process_id": "12345", + "process_memory_size": 104857600, + "thread_id": "1", + "command_line": "TestApp.exe --test" + }, + "@request": { + "client_ip_address": "10.0.0.100", + "http_method": "POST", + "user_agent": "TestAgent/1.0", + "is_secure": true, + "host": "test.example.com", + "path": "/api/test", + "port": 443 + } +} diff --git a/tests/Exceptionless.Tests/Controllers/Data/event-serialization-response.json b/tests/Exceptionless.Tests/Controllers/Data/event-serialization-response.json new file mode 100644 index 0000000000..5c81f267a7 --- /dev/null +++ b/tests/Exceptionless.Tests/Controllers/Data/event-serialization-response.json @@ -0,0 +1,48 @@ +{ + "id": "", + "organization_id": "537650f3b77efe23a47914f3", + "project_id": "537650f3b77efe23a47914f4", + "stack_id": "", + "is_first_occurrence": true, + "created_utc": "2026-01-15T12:00:00", + "type": "error", + "date": "2026-01-15T12:00:00+00:00", + "tags": [ + "test", + "serialization" + ], + "message": "Test error for serialization verification", + "data": { + "@request": { + "user_agent": "TestAgent/1.0", + "http_method": "POST", + "is_secure": true, + "host": "test.example.com", + "port": 443, + "path": "/api/test", + "client_ip_address": "10.0.0.100", + "data": { + "@is_bot": false + } + }, + "@submission_client": { + "user_agent": "fluentrest", + "version": "10.1.0.0" + }, + "@environment": { + "processor_count": 8, + "total_physical_memory": 17179869184, + "available_physical_memory": 8589934592, + "command_line": "TestApp.exe --test", + "process_name": "TestApp", + "process_id": "12345", + "process_memory_size": 104857600, + "thread_id": "1", + "o_s_name": "Windows 11", + "o_s_version": "10.0.22621", + "ip_address": "192.168.1.100", + "machine_name": "TEST-MACHINE", + "runtime_version": ".NET 8.0.1" + } + } +} diff --git a/tests/Exceptionless.Tests/Controllers/Data/swagger.json b/tests/Exceptionless.Tests/Controllers/Data/swagger.json new file mode 100644 index 0000000000..1b5fe4ba62 --- /dev/null +++ b/tests/Exceptionless.Tests/Controllers/Data/swagger.json @@ -0,0 +1,7800 @@ +{ + "openapi": "3.0.4", + "info": { + "title": "Exceptionless API", + "termsOfService": "https://exceptionless.com/terms/", + "contact": { + "name": "Exceptionless", + "url": "https://github.com/exceptionless/Exceptionless", + "email": "" + }, + "license": { + "name": "Apache License 2.0", + "url": "https://github.com/exceptionless/Exceptionless/blob/main/LICENSE.txt" + }, + "version": "v2" + }, + "paths": { + "/api/v2/auth/login": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Login", + "description": "Log in with your email address and password to generate a token scoped with your users roles.\n \n```{ \"email\": \"noreply@exceptionless.io\", \"password\": \"exceptionless\" }```\n \nThis token can then be used to access the api. You can use this token in the header (bearer authentication)\nor append it onto the query string: ?access_token=MY_TOKEN\n \nPlease note that you can also use this token on the documentation site by placing it in the\nheaders api_key input box.", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Login" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "401": { + "description": "Login failed" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/logout": { + "get": { + "tags": [ + "Auth" + ], + "summary": "Logout the current user and remove the current access token", + "responses": { + "200": { + "description": "User successfully logged-out" + }, + "401": { + "description": "User not logged in" + }, + "403": { + "description": "Current action is not supported with user access token" + } + } + } + }, + "/api/v2/auth/signup": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign up", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Signup" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "401": { + "description": "Sign-up failed" + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/github": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign in with GitHub", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/google": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign in with Google", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/facebook": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign in with Facebook", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/live": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign in with Microsoft", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/unlink/{providerName}": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Removes an external login provider from the account", + "parameters": [ + { + "name": "providerName", + "in": "path", + "description": "The provider name.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "The provider user id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "400": { + "description": "Invalid provider name." + } + } + } + }, + "/api/v2/auth/change-password": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Change password", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChangePasswordModel" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/forgot-password/{email}": { + "get": { + "tags": [ + "Auth" + ], + "summary": "Forgot password", + "parameters": [ + { + "name": "email", + "in": "path", + "description": "The email address.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Forgot password email was sent." + }, + "400": { + "description": "Invalid email address." + } + } + } + }, + "/api/v2/auth/reset-password": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Reset password", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPasswordModel" + } + } + } + }, + "responses": { + "200": { + "description": "Password reset email was sent." + }, + "422": { + "description": "Invalid reset password model." + } + } + } + }, + "/api/v2/auth/cancel-reset-password/{token}": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Cancel reset password", + "parameters": [ + { + "name": "token", + "in": "path", + "description": "The password reset token.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Password reset email was cancelled." + }, + "400": { + "description": "Invalid password reset token." + } + } + } + }, + "/api/v2/events/count": { + "get": { + "tags": [ + "Event" + ], + "summary": "Count", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "aggregations", + "in": "query", + "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CountResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/CountResult" + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/organizations/{organizationId}/events/count": { + "get": { + "tags": [ + "Event" + ], + "summary": "Count by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "aggregations", + "in": "query", + "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CountResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/CountResult" + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/projects/{projectId}/events/count": { + "get": { + "tags": [ + "Event" + ], + "summary": "Count by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "aggregations", + "in": "query", + "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If mode is set to stack_new, then additional filters will be added.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CountResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/CountResult" + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/events/{id}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by id", + "operationId": "GetPersistentEventById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the event.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersistentEvent" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + }, + "404": { + "description": "The event occurrence could not be found." + }, + "426": { + "description": "Unable to view event occurrence due to plan limits." + } + } + } + }, + "/api/v2/events": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get all", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + }, + "post": { + "tags": [ + "Event" + ], + "summary": "Submit event by POST", + "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", + "parameters": [ + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "string", + "example": "" + } + }, + "text/plain": { + "schema": { + "type": "string", + "example": "" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/organizations/{organizationId}/events": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The organization could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/events": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + }, + "post": { + "tags": [ + "Event" + ], + "summary": "Submit event by POST for a specific project", + "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "string", + "example": "" + } + }, + "text/plain": { + "schema": { + "type": "string", + "example": "" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/stacks/{stackId}/events": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by stack", + "parameters": [ + { + "name": "stackId", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The stack could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/events/by-ref/{referenceId}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by reference id", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/events/by-ref/{referenceId}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by reference id", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/events/sessions/{sessionId}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of all sessions or events by a session id", + "parameters": [ + { + "name": "sessionId", + "in": "path", + "description": "An identifier that represents a session of events.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/events/sessions/{sessionId}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of by a session id", + "parameters": [ + { + "name": "sessionId", + "in": "path", + "description": "An identifier that represents a session of events.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/events/sessions": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of all sessions", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/organizations/{organizationId}/events/sessions": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of all sessions", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/events/sessions": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of all sessions", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/events/by-ref/{referenceId}/user-description": { + "post": { + "tags": [ + "Event" + ], + "summary": "Set user description", + "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The user description.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserDescription" + } + } + } + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "Description must be specified." + }, + "404": { + "description": "The event occurrence with the specified reference id could not be found." + } + } + } + }, + "/api/v2/projects/{projectId}/events/by-ref/{referenceId}/user-description": { + "post": { + "tags": [ + "Event" + ], + "summary": "Set user description", + "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The user description.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserDescription" + } + } + } + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "Description must be specified." + }, + "404": { + "description": "The event occurrence with the specified reference id could not be found." + } + } + } + }, + "/api/v2/events/session/heartbeat": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit heartbeat", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "The session id or user id.", + "schema": { + "type": "string" + } + }, + { + "name": "close", + "in": "query", + "description": "If true, the session will be closed.", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/events/submit": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit event by GET", + "description": "You can submit an event using an HTTP GET and query string parameters. Any unknown query string parameters will be added to the extended data of the event.\n \nFeature usage named build with a duration of 10:\n```/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "type", + "in": "query", + "description": "The event type (ie. error, log message, feature usage).", + "schema": { + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query string parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/events/submit/{type}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit event type by GET", + "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage event named build with a value of 10:\n```/events/submit/usage?access_token=YOUR_API_KEY&source=build&value=10```\n \nLog event with message, geo and extended data\n```/events/submit/log?access_token=YOUR_API_KEY&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "type", + "in": "path", + "description": "The event type (ie. error, log message, feature usage).", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query string parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/projects/{projectId}/events/submit": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit event type by GET for a specific project", + "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query String parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/projects/{projectId}/events/submit/{type}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit event type by GET for a specific project", + "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "type", + "in": "path", + "description": "The event type (ie. error, log message, feature usage).", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query String parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/events/{ids}": { + "delete": { + "tags": [ + "Event" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of event identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more event occurrences were not found." + }, + "500": { + "description": "An error occurred while deleting one or more event occurrences." + } + } + } + }, + "/api/v2/organizations": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get all", + "parameters": [ + { + "name": "mode", + "in": "query", + "description": "If no mode is set then a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "Organization" + ], + "summary": "Create", + "requestBody": { + "description": "The organization.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewOrganization" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "400": { + "description": "An error occurred while creating the organization." + }, + "409": { + "description": "The organization already exists." + } + } + } + }, + "/api/v2/organizations/{id}": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get by id", + "operationId": "GetOrganizationById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + }, + "patch": { + "tags": [ + "Organization" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "400": { + "description": "An error occurred while updating the organization." + }, + "404": { + "description": "The organization could not be found." + } + } + }, + "put": { + "tags": [ + "Organization" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "400": { + "description": "An error occurred while updating the organization." + }, + "404": { + "description": "The organization could not be found." + } + } + } + }, + "/api/v2/organizations/{ids}": { + "delete": { + "tags": [ + "Organization" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of organization identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more organizations were not found." + }, + "500": { + "description": "An error occurred while deleting one or more organizations." + } + } + } + }, + "/api/v2/organizations/invoice/{id}": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get invoice", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the invoice.", + "required": true, + "schema": { + "minLength": 10, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Invoice" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Invoice" + } + } + } + }, + "404": { + "description": "The invoice was not found." + } + } + } + }, + "/api/v2/organizations/{id}/invoices": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get invoices", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "before", + "in": "query", + "description": "A cursor for use in pagination. before is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, starting with obj_bar, your subsequent call can include before=obj_bar in order to fetch the previous page of the list.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "A cursor for use in pagination. after is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include after=obj_foo in order to fetch the next page of the list.", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 12 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InvoiceGridModel" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InvoiceGridModel" + } + } + } + } + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/{id}/plans": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get plans", + "description": "Gets available plans for a specific organization.", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BillingPlan" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BillingPlan" + } + } + } + } + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/{id}/change-plan": { + "post": { + "tags": [ + "Organization" + ], + "summary": "Change plan", + "description": "Upgrades or downgrades the organizations plan.", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "planId", + "in": "query", + "description": "The identifier of the plan.", + "schema": { + "type": "string" + } + }, + { + "name": "stripeToken", + "in": "query", + "description": "The token returned from the stripe service.", + "schema": { + "type": "string" + } + }, + { + "name": "last4", + "in": "query", + "description": "The last four numbers of the card.", + "schema": { + "type": "string" + } + }, + { + "name": "couponId", + "in": "query", + "description": "The coupon id.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChangePlanResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ChangePlanResult" + } + } + } + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/{id}/users/{email}": { + "post": { + "tags": [ + "Organization" + ], + "summary": "Add user", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "email", + "in": "path", + "description": "The email address of the user you wish to add to your organization.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "404": { + "description": "The organization was not found." + }, + "426": { + "description": "Please upgrade your plan to add an additional user." + } + } + }, + "delete": { + "tags": [ + "Organization" + ], + "summary": "Remove user", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "email", + "in": "path", + "description": "The email address of the user you wish to remove from your organization.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "The error occurred while removing the user from your organization" + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/{id}/data/{key}": { + "post": { + "tags": [ + "Organization" + ], + "summary": "Add custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "path", + "description": "The key name of the data object.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "Any string value.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The organization was not found." + } + } + }, + "delete": { + "tags": [ + "Organization" + ], + "summary": "Remove custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "path", + "description": "The key name of the data object.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/check-name": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Check for unique name", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "The organization name to check.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "201": { + "description": "The organization name is available." + }, + "204": { + "description": "The organization name is not available." + } + } + } + }, + "/api/v2/projects": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get all", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewProject" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Create", + "requestBody": { + "description": "The project.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewProject" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "400": { + "description": "An error occurred while creating the project." + }, + "409": { + "description": "The project already exists." + } + } + } + }, + "/api/v2/organizations/{organizationId}/projects": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get all", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewProject" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + } + }, + "/api/v2/projects/{id}": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get by id", + "operationId": "GetProjectById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + }, + "patch": { + "tags": [ + "Project" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "400": { + "description": "An error occurred while updating the project." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "put": { + "tags": [ + "Project" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "400": { + "description": "An error occurred while updating the project." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/{ids}": { + "delete": { + "tags": [ + "Project" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of project identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more projects were not found." + }, + "500": { + "description": "An error occurred while deleting one or more projects." + } + } + } + }, + "/api/v2/projects/config": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get configuration settings", + "parameters": [ + { + "name": "v", + "in": "query", + "description": "The client configuration version.", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ClientConfiguration" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ClientConfiguration" + } + } + } + }, + "304": { + "description": "The client configuration version is the current version." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/{id}/config": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get configuration settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "v", + "in": "query", + "description": "The client configuration version.", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ClientConfiguration" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ClientConfiguration" + } + } + } + }, + "304": { + "description": "The client configuration version is the current version." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Add configuration value", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the configuration object.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "The configuration value.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid configuration value." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": [ + "Project" + ], + "summary": "Remove configuration value", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the configuration object.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid key value." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/{id}/reset-data": { + "get": { + "tags": [ + "Project" + ], + "summary": "Reset project data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/users/{userId}/projects/{id}/notifications": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + }, + "put": { + "tags": [ + "Project" + ], + "summary": "Set user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Set user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": [ + "Project" + ], + "summary": "Remove user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/{id}/{integration}/notifications": { + "put": { + "tags": [ + "Project" + ], + "summary": "Set an integrations notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "integration", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project or integration could not be found." + }, + "426": { + "description": "Please upgrade your plan to enable integrations." + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Set an integrations notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "integration", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project or integration could not be found." + }, + "426": { + "description": "Please upgrade your plan to enable integrations." + } + } + } + }, + "/api/v2/projects/{id}/promotedtabs": { + "put": { + "tags": [ + "Project" + ], + "summary": "Promote tab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "The tab name.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid tab name." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Promote tab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "The tab name.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid tab name." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": [ + "Project" + ], + "summary": "Demote tab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "The tab name.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid tab name." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/check-name": { + "get": { + "tags": [ + "Project" + ], + "summary": "Check for unique name", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "The project name to check.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "The project name is available." + }, + "204": { + "description": "The project name is not available." + } + } + } + }, + "/api/v2/organizations/{organizationId}/projects/check-name": { + "get": { + "tags": [ + "Project" + ], + "summary": "Check for unique name", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "The project name to check.", + "schema": { + "type": "string" + } + }, + { + "name": "organizationId", + "in": "path", + "description": "If set the check name will be scoped to a specific organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "The project name is available." + }, + "204": { + "description": "The project name is not available." + } + } + } + }, + "/api/v2/projects/{id}/data": { + "post": { + "tags": [ + "Project" + ], + "summary": "Add custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the data object.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Any string value.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid key or value." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": [ + "Project" + ], + "summary": "Remove custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the data object.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid key or value." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/stacks/{id}": { + "get": { + "tags": [ + "Stack" + ], + "summary": "Get by id", + "operationId": "GetStackById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the `time` filter. This is used for time zone support.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Stack" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Stack" + } + } + } + }, + "404": { + "description": "The stack could not be found." + } + } + } + }, + "/api/v2/stacks/{ids}/mark-fixed": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Mark fixed", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + }, + { + "name": "version", + "in": "query", + "description": "A version number that the stack was fixed in.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "404": { + "description": "One or more stacks could not be found." + } + } + } + }, + "/api/v2/stacks/{ids}/mark-snoozed": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Mark the selected stacks as snoozed", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + }, + { + "name": "snoozeUntilUtc", + "in": "query", + "description": "A time that the stack should be snoozed until.", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "404": { + "description": "One or more stacks could not be found." + } + } + } + }, + "/api/v2/stacks/{id}/add-link": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Add reference link", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The reference link.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid reference link." + }, + "404": { + "description": "The stack could not be found." + } + } + } + }, + "/api/v2/stacks/{id}/remove-link": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Remove reference link", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The reference link.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "204": { + "description": "The reference link was removed." + }, + "400": { + "description": "Invalid reference link." + }, + "404": { + "description": "The stack could not be found." + } + } + } + }, + "/api/v2/stacks/{ids}/mark-critical": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Mark future occurrences as critical", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "One or more stacks could not be found." + } + } + }, + "delete": { + "tags": [ + "Stack" + ], + "summary": "Mark future occurrences as not critical", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The stacks were marked as not critical." + }, + "404": { + "description": "One or more stacks could not be found." + } + } + } + }, + "/api/v2/stacks/{ids}/change-status": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Change stack status", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "The status that the stack should be changed to.\n\nopen\n\nfixed\n\nregressed\n\nsnoozed\n\nignored\n\ndiscarded", + "schema": { + "$ref": "#/components/schemas/StackStatus" + }, + "x-enumNames": [ + "Open", + "Fixed", + "Regressed", + "Snoozed", + "Ignored", + "Discarded" + ] + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "One or more stacks could not be found." + } + } + } + }, + "/api/v2/stacks/{id}/promote": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Promote to external service", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The stack could not be found." + }, + "426": { + "description": "Promote to External is a premium feature used to promote an error stack to an external system." + }, + "501": { + "description": "No promoted web hooks are configured for this project." + } + } + } + }, + "/api/v2/stacks/{ids}": { + "delete": { + "tags": [ + "Stack" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more stacks were not found." + }, + "500": { + "description": "An error occurred while deleting one or more stacks." + } + } + } + }, + "/api/v2/stacks": { + "get": { + "tags": [ + "Stack" + ], + "summary": "Get all", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/organizations/{organizationId}/stacks": { + "get": { + "tags": [ + "Stack" + ], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The organization could not be found." + }, + "426": { + "description": "Unable to view stack occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/stacks": { + "get": { + "tags": [ + "Stack" + ], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The organization could not be found." + }, + "426": { + "description": "Unable to view stack occurrences for the suspended organization." + } + } + } + }, + "/api/v2/organizations/{organizationId}/tokens": { + "get": { + "tags": [ + "Token" + ], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewToken" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + }, + "post": { + "tags": [ + "Token" + ], + "summary": "Create for organization", + "description": "This is a helper action that makes it easier to create a token for a specific organization.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewToken" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while creating the token." + }, + "409": { + "description": "The token already exists." + } + } + } + }, + "/api/v2/projects/{projectId}/tokens": { + "get": { + "tags": [ + "Token" + ], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewToken" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": [ + "Token" + ], + "summary": "Create for project", + "description": "This is a helper action that makes it easier to create a token for a specific project.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewToken" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while creating the token." + }, + "404": { + "description": "The project could not be found." + }, + "409": { + "description": "The token already exists." + } + } + } + }, + "/api/v2/projects/{projectId}/tokens/default": { + "get": { + "tags": [ + "Token" + ], + "summary": "Get a projects default token", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/tokens/{id}": { + "get": { + "tags": [ + "Token" + ], + "summary": "Get by id", + "operationId": "GetTokenById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the token.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "404": { + "description": "The token could not be found." + } + } + }, + "patch": { + "tags": [ + "Token" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the token.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while updating the token." + }, + "404": { + "description": "The token could not be found." + } + } + }, + "put": { + "tags": [ + "Token" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the token.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while updating the token." + }, + "404": { + "description": "The token could not be found." + } + } + } + }, + "/api/v2/tokens": { + "post": { + "tags": [ + "Token" + ], + "summary": "Create", + "description": "To create a new token, you must specify an organization_id. There are three valid scopes: client, user and admin.", + "requestBody": { + "description": "The token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewToken" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while creating the token." + }, + "409": { + "description": "The token already exists." + } + } + } + }, + "/api/v2/tokens/{ids}": { + "delete": { + "tags": [ + "Token" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of token identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more tokens were not found." + }, + "500": { + "description": "An error occurred while deleting one or more tokens." + } + } + } + }, + "/api/v2/users/me": { + "get": { + "tags": [ + "User" + ], + "summary": "Get current user", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewCurrentUser" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewCurrentUser" + } + } + } + }, + "404": { + "description": "The current user could not be found." + } + } + }, + "delete": { + "tags": [ + "User" + ], + "summary": "Delete current user", + "responses": { + "202": { + "description": "Accepted" + }, + "404": { + "description": "The current user could not be found." + } + } + } + }, + "/api/v2/users/{id}": { + "get": { + "tags": [ + "User" + ], + "summary": "Get by id", + "operationId": "GetUserById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + }, + "404": { + "description": "The user could not be found." + } + } + }, + "patch": { + "tags": [ + "User" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + }, + "400": { + "description": "An error occurred while updating the user." + }, + "404": { + "description": "The user could not be found." + } + } + }, + "put": { + "tags": [ + "User" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + }, + "400": { + "description": "An error occurred while updating the user." + }, + "404": { + "description": "The user could not be found." + } + } + } + }, + "/api/v2/organizations/{organizationId}/users": { + "get": { + "tags": [ + "User" + ], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewUser" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + } + }, + "/api/v2/users/{ids}": { + "delete": { + "tags": [ + "User" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of user identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more users were not found." + }, + "500": { + "description": "An error occurred while deleting one or more users." + } + } + } + }, + "/api/v2/users/{id}/email-address/{email}": { + "post": { + "tags": [ + "User" + ], + "summary": "Update email address", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "email", + "in": "path", + "description": "The new email address.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateEmailAddressResult" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/UpdateEmailAddressResult" + } + } + } + }, + "400": { + "description": "An error occurred while updating the users email address." + }, + "422": { + "description": "Validation error" + }, + "429": { + "description": "Update email address rate limit reached." + } + } + } + }, + "/api/v2/users/verify-email-address/{token}": { + "get": { + "tags": [ + "User" + ], + "summary": "Verify email address", + "parameters": [ + { + "name": "token", + "in": "path", + "description": "The token identifier.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The user could not be found." + }, + "422": { + "description": "Verify Email Address Token has expired." + } + } + } + }, + "/api/v2/users/{id}/resend-verification-email": { + "get": { + "tags": [ + "User" + ], + "summary": "Resend verification email", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "The user verification email has been sent." + }, + "404": { + "description": "The user could not be found." + } + } + } + }, + "/api/v2/projects/{projectId}/webhooks": { + "get": { + "tags": [ + "WebHook" + ], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebHook" + } + } + }, + "application/problem+json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebHook" + } + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/webhooks/{id}": { + "get": { + "tags": [ + "WebHook" + ], + "summary": "Get by id", + "operationId": "GetWebHookById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the web hook.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebHook" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/WebHook" + } + } + } + }, + "404": { + "description": "The web hook could not be found." + } + } + } + }, + "/api/v2/webhooks": { + "post": { + "tags": [ + "WebHook" + ], + "summary": "Create", + "requestBody": { + "description": "The web hook.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewWebHook" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebHook" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/WebHook" + } + } + } + }, + "400": { + "description": "An error occurred while creating the web hook." + }, + "409": { + "description": "The web hook already exists." + } + } + } + }, + "/api/v2/webhooks/{ids}": { + "delete": { + "tags": [ + "WebHook" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of web hook identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more web hooks were not found." + }, + "500": { + "description": "An error occurred while deleting one or more web hooks." + } + } + } + } + }, + "components": { + "schemas": { + "BillingPlan": { + "required": [ + "description", + "id", + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "price": { + "type": "number", + "format": "double" + }, + "max_projects": { + "type": "integer", + "format": "int32" + }, + "max_users": { + "type": "integer", + "format": "int32" + }, + "retention_days": { + "type": "integer", + "format": "int32" + }, + "max_events_per_month": { + "type": "integer", + "format": "int32" + }, + "has_premium_features": { + "type": "boolean" + }, + "is_hidden": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "BillingStatus": { + "enum": [ + 0, + 1, + 2, + 3, + 4 + ], + "type": "integer", + "description": "\n\n0 = Trialing\n\n1 = Active\n\n2 = PastDue\n\n3 = Canceled\n\n4 = Unpaid", + "format": "int32", + "x-enumNames": [ + "Trialing", + "Active", + "PastDue", + "Canceled", + "Unpaid" + ] + }, + "ChangePasswordModel": { + "required": [ + "current_password", + "password" + ], + "type": "object", + "properties": { + "current_password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + } + }, + "additionalProperties": false + }, + "ChangePlanResult": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "message": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "ClientConfiguration": { + "type": "object", + "properties": { + "version": { + "type": "integer", + "format": "int32" + }, + "settings": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "readOnly": true + } + }, + "additionalProperties": false + }, + "CountResult": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int64" + }, + "aggregations": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/IAggregate" + }, + "nullable": true + }, + "data": { + "type": "object", + "additionalProperties": { + "nullable": true + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "ExternalAuthInfo": { + "required": [ + "clientId", + "code", + "redirectUri" + ], + "type": "object", + "properties": { + "clientId": { + "minLength": 1, + "type": "string" + }, + "code": { + "minLength": 1, + "type": "string" + }, + "redirectUri": { + "minLength": 1, + "type": "string" + }, + "inviteToken": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "IAggregate": { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "nullable": true + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "Invite": { + "required": [ + "date_added", + "email_address", + "token" + ], + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "email_address": { + "type": "string" + }, + "date_added": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "Invoice": { + "required": [ + "date", + "id", + "organization_id", + "organization_name", + "paid", + "total" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "organization_name": { + "type": "string" + }, + "date": { + "type": "string", + "format": "date-time" + }, + "paid": { + "type": "boolean" + }, + "total": { + "type": "number", + "format": "double" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InvoiceLineItem" + } + } + }, + "additionalProperties": false + }, + "InvoiceGridModel": { + "required": [ + "date", + "id", + "paid" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "date": { + "type": "string", + "format": "date-time" + }, + "paid": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "InvoiceLineItem": { + "required": [ + "amount", + "description" + ], + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "date": { + "type": "string", + "nullable": true + }, + "amount": { + "type": "number", + "format": "double" + } + }, + "additionalProperties": false + }, + "Login": { + "required": [ + "email", + "password" + ], + "type": "object", + "properties": { + "email": { + "minLength": 1, + "type": "string", + "description": "The email address or domain username" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + }, + "invite_token": { + "maxLength": 40, + "minLength": 40, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "NewOrganization": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NewProject": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "delete_bot_data_enabled": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "NewToken": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "default_project_id": { + "type": "string", + "nullable": true + }, + "scopes": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "expires_utc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "notes": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "NewWebHook": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "url": { + "type": "string" + }, + "event_types": { + "type": "array", + "items": { + "type": "string" + } + }, + "version": { + "type": "string", + "description": "The schema version that should be used.", + "nullable": true + } + }, + "additionalProperties": false + }, + "NotificationSettings": { + "type": "object", + "properties": { + "send_daily_summary": { + "type": "boolean" + }, + "report_new_errors": { + "type": "boolean" + }, + "report_critical_errors": { + "type": "boolean" + }, + "report_event_regressions": { + "type": "boolean" + }, + "report_new_events": { + "type": "boolean" + }, + "report_critical_events": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "OAuthAccount": { + "required": [ + "provider", + "provider_user_id", + "username" + ], + "type": "object", + "properties": { + "provider": { + "type": "string" + }, + "provider_user_id": { + "type": "string" + }, + "username": { + "type": "string" + }, + "extra_data": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "readOnly": true + } + }, + "additionalProperties": false + }, + "PersistentEvent": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "stack_id": { + "type": "string" + }, + "is_first_occurrence": { + "type": "boolean" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "idx": { + "type": "object", + "additionalProperties": { } + }, + "type": { + "type": "string", + "nullable": true + }, + "source": { + "type": "string", + "nullable": true + }, + "date": { + "type": "string", + "format": "date-time" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, + "message": { + "type": "string", + "nullable": true + }, + "geo": { + "type": "string", + "nullable": true + }, + "value": { + "type": "number", + "format": "double", + "nullable": true + }, + "count": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "data": { + "type": "object", + "additionalProperties": { }, + "nullable": true + }, + "reference_id": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "ResetPasswordModel": { + "required": [ + "password", + "password_reset_token" + ], + "type": "object", + "properties": { + "password_reset_token": { + "maxLength": 40, + "minLength": 40, + "type": "string" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + } + }, + "additionalProperties": false + }, + "Signup": { + "required": [ + "email", + "name", + "password" + ], + "type": "object", + "properties": { + "name": { + "minLength": 1, + "type": "string" + }, + "email": { + "minLength": 1, + "type": "string", + "description": "The email address or domain username" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + }, + "invite_token": { + "maxLength": 40, + "minLength": 40, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "Stack": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/StackStatus" + }, + "snooze_until_utc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "signature_hash": { + "type": "string" + }, + "signature_info": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "fixed_in_version": { + "type": "string", + "nullable": true + }, + "date_fixed": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "title": { + "type": "string" + }, + "total_occurrences": { + "type": "integer", + "format": "int32" + }, + "first_occurrence": { + "type": "string", + "format": "date-time" + }, + "last_occurrence": { + "type": "string", + "format": "date-time" + }, + "description": { + "type": "string", + "nullable": true + }, + "occurrences_are_critical": { + "type": "boolean" + }, + "references": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "duplicate_signature": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "updated_utc": { + "type": "string", + "format": "date-time" + }, + "is_deleted": { + "type": "boolean" + }, + "allow_notifications": { + "type": "boolean", + "readOnly": true + } + }, + "additionalProperties": false + }, + "StackStatus": { + "enum": [ + "open", + "fixed", + "regressed", + "snoozed", + "ignored", + "discarded" + ], + "type": "string", + "description": "\n\nopen\n\nfixed\n\nregressed\n\nsnoozed\n\nignored\n\ndiscarded", + "x-enumNames": [ + "Open", + "Fixed", + "Regressed", + "Snoozed", + "Ignored", + "Discarded" + ] + }, + "StringStringValuesKeyValuePair": { + "type": "object", + "properties": { + "key": { + "type": "string", + "nullable": true + }, + "value": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "StringValueFromBody": { + "type": "object", + "properties": { + "value": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "TokenResult": { + "required": [ + "token" + ], + "type": "object", + "properties": { + "token": { + "minLength": 1, + "type": "string" + } + }, + "additionalProperties": false + }, + "UpdateEmailAddressResult": { + "required": [ + "is_verified" + ], + "type": "object", + "properties": { + "is_verified": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "UsageHourInfo": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "total": { + "type": "integer", + "format": "int32" + }, + "blocked": { + "type": "integer", + "format": "int32" + }, + "discarded": { + "type": "integer", + "format": "int32" + }, + "too_big": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "UsageInfo": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "limit": { + "type": "integer", + "format": "int32" + }, + "total": { + "type": "integer", + "format": "int32" + }, + "blocked": { + "type": "integer", + "format": "int32" + }, + "discarded": { + "type": "integer", + "format": "int32" + }, + "too_big": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "User": { + "required": [ + "email_address", + "full_name" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_ids": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + }, + "readOnly": true + }, + "password": { + "type": "string", + "nullable": true + }, + "salt": { + "type": "string", + "nullable": true + }, + "password_reset_token": { + "type": "string", + "nullable": true + }, + "password_reset_token_expiration": { + "type": "string", + "format": "date-time" + }, + "o_auth_accounts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OAuthAccount" + }, + "readOnly": true + }, + "full_name": { + "minLength": 1, + "type": "string" + }, + "email_address": { + "minLength": 1, + "type": "string", + "format": "email" + }, + "email_notifications_enabled": { + "type": "boolean" + }, + "is_email_address_verified": { + "type": "boolean" + }, + "verify_email_address_token": { + "type": "string", + "nullable": true + }, + "verify_email_address_token_expiration": { + "type": "string", + "format": "date-time" + }, + "is_active": { + "type": "boolean" + }, + "roles": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "updated_utc": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "UserDescription": { + "type": "object", + "properties": { + "email_address": { + "type": "string", + "nullable": true + }, + "description": { + "type": "string", + "nullable": true + }, + "data": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "ViewCurrentUser": { + "type": "object", + "properties": { + "hash": { + "type": "string", + "nullable": true + }, + "has_local_account": { + "type": "boolean" + }, + "o_auth_accounts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OAuthAccount" + } + }, + "id": { + "type": "string" + }, + "organization_ids": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "full_name": { + "type": "string" + }, + "email_address": { + "type": "string" + }, + "email_notifications_enabled": { + "type": "boolean" + }, + "is_email_address_verified": { + "type": "boolean" + }, + "is_active": { + "type": "boolean" + }, + "is_invite": { + "type": "boolean" + }, + "roles": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "ViewOrganization": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "plan_id": { + "type": "string" + }, + "plan_name": { + "type": "string" + }, + "plan_description": { + "type": "string" + }, + "card_last4": { + "type": "string", + "nullable": true + }, + "subscribe_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "billing_change_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "billing_changed_by_user_id": { + "type": "string", + "nullable": true + }, + "billing_status": { + "$ref": "#/components/schemas/BillingStatus" + }, + "billing_price": { + "type": "number", + "format": "double" + }, + "max_events_per_month": { + "type": "integer", + "format": "int32" + }, + "bonus_events_per_month": { + "type": "integer", + "format": "int32" + }, + "bonus_expiration": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "retention_days": { + "type": "integer", + "format": "int32" + }, + "is_suspended": { + "type": "boolean" + }, + "suspension_code": { + "type": "string", + "nullable": true + }, + "suspension_notes": { + "type": "string", + "nullable": true + }, + "suspension_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "has_premium_features": { + "type": "boolean" + }, + "max_users": { + "type": "integer", + "format": "int32" + }, + "max_projects": { + "type": "integer", + "format": "int32" + }, + "project_count": { + "type": "integer", + "format": "int64" + }, + "stack_count": { + "type": "integer", + "format": "int64" + }, + "event_count": { + "type": "integer", + "format": "int64" + }, + "invites": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Invite" + } + }, + "usage_hours": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageHourInfo" + } + }, + "usage": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageInfo" + } + }, + "data": { + "type": "object", + "additionalProperties": { }, + "nullable": true + }, + "is_throttled": { + "type": "boolean" + }, + "is_over_monthly_limit": { + "type": "boolean" + }, + "is_over_request_limit": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "ViewProject": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "organization_id": { + "type": "string" + }, + "organization_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "delete_bot_data_enabled": { + "type": "boolean" + }, + "data": { + "type": "object", + "additionalProperties": { }, + "nullable": true + }, + "promoted_tabs": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "is_configured": { + "type": "boolean", + "nullable": true + }, + "stack_count": { + "type": "integer", + "format": "int64" + }, + "event_count": { + "type": "integer", + "format": "int64" + }, + "has_premium_features": { + "type": "boolean" + }, + "has_slack_integration": { + "type": "boolean" + }, + "usage_hours": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageHourInfo" + } + }, + "usage": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageInfo" + } + } + }, + "additionalProperties": false + }, + "ViewToken": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "user_id": { + "type": "string", + "nullable": true + }, + "default_project_id": { + "type": "string", + "nullable": true + }, + "scopes": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "expires_utc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "notes": { + "type": "string", + "nullable": true + }, + "is_disabled": { + "type": "boolean" + }, + "is_suspended": { + "type": "boolean" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "updated_utc": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "ViewUser": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_ids": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "full_name": { + "type": "string" + }, + "email_address": { + "type": "string" + }, + "email_notifications_enabled": { + "type": "boolean" + }, + "is_email_address_verified": { + "type": "boolean" + }, + "is_active": { + "type": "boolean" + }, + "is_invite": { + "type": "boolean" + }, + "roles": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "WebHook": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "url": { + "type": "string" + }, + "event_types": { + "type": "array", + "items": { + "type": "string" + } + }, + "is_enabled": { + "type": "boolean" + }, + "version": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + } + }, + "securitySchemes": { + "Basic": { + "type": "http", + "description": "Basic HTTP Authentication", + "scheme": "basic" + }, + "Bearer": { + "type": "http", + "description": "Authorization token. Example: \"Bearer {apikey}\"", + "scheme": "bearer" + }, + "Token": { + "type": "apiKey", + "description": "Authorization token. Example: \"Bearer {apikey}\"", + "name": "access_token", + "in": "query" + } + } + }, + "security": [ + { + "Basic": [ ], + "Bearer": [ ], + "Token": [ ] + } + ] +} \ No newline at end of file diff --git a/tests/Exceptionless.Tests/Controllers/EventControllerTests.cs b/tests/Exceptionless.Tests/Controllers/EventControllerTests.cs index 56577daa01..fb067e08f2 100644 --- a/tests/Exceptionless.Tests/Controllers/EventControllerTests.cs +++ b/tests/Exceptionless.Tests/Controllers/EventControllerTests.cs @@ -1542,4 +1542,41 @@ private static Dictionary ParseLinkHeaderValue(string[] links) return result; } + + [Fact] + public async Task PostEvent_WithEnvironmentAndRequestInfo_ReturnsCorrectSnakeCaseSerialization() + { + TimeProvider.SetUtcNow(new DateTime(2026, 1, 15, 12, 0, 0, DateTimeKind.Utc)); + + string dataPath = Path.Combine("..", "..", "..", "Controllers", "Data"); + string eventJson = await File.ReadAllTextAsync(Path.Combine(dataPath, "event-serialization-input.json")); + + await SendRequestAsync(r => r + .Post() + .AsTestOrganizationClientUser() + .AppendPath("events") + .Content(eventJson, "application/json") + .StatusCodeShouldBeAccepted() + ); + + var processEventsJob = GetService(); + await processEventsJob.RunAsync(); + await RefreshDataAsync(); + + var events = await _eventRepository.GetAllAsync(); + var processedEvent = events.Documents.Single(); + + var response = await SendRequestAsync(r => r + .AsGlobalAdminUser() + .AppendPaths("events", processedEvent.Id) + .StatusCodeShouldBeOk() + ); + + string actualJson = await response.Content.ReadAsStringAsync(); + string expectedJson = (await File.ReadAllTextAsync(Path.Combine(dataPath, "event-serialization-response.json"))) + .Replace("", processedEvent.Id) + .Replace("", processedEvent.StackId); + + Assert.Equal(expectedJson, actualJson); + } } diff --git a/tests/Exceptionless.Tests/Controllers/OpenApiControllerTests.cs b/tests/Exceptionless.Tests/Controllers/OpenApiControllerTests.cs new file mode 100644 index 0000000000..497f193977 --- /dev/null +++ b/tests/Exceptionless.Tests/Controllers/OpenApiControllerTests.cs @@ -0,0 +1,27 @@ +using Exceptionless.Tests.Extensions; +using Xunit; +using Xunit.Abstractions; + +namespace Exceptionless.Tests.Controllers; + +public class OpenApiControllerTests : IntegrationTestsBase +{ + public OpenApiControllerTests(ITestOutputHelper output, AppWebHostFactory factory) : base(output, factory) + { + } + + [Fact] + public async Task GetSwaggerJson_ReturnsExpectedBaseline() + { + var response = await SendRequestAsync(r => r + .BaseUri(_server.BaseAddress) + .AppendPaths("docs", "v2", "swagger.json") + .StatusCodeShouldBeOk() + ); + + string baselinePath = Path.Combine("..", "..", "..", "Controllers", "Data", "swagger.json"); + string expectedJson = await File.ReadAllTextAsync(baselinePath); + string actualJson = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedJson, actualJson); + } +} From 05feca3cb5a18ea5cb0c4438f09becd7dcfad537 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Thu, 4 Dec 2025 22:45:59 -0600 Subject: [PATCH 11/14] Fixed swagger gen issues and .NET 10 OpenAPi issues --- .../Exceptionless.Insulation.csproj | 4 - src/Exceptionless.Web/ClientApp/package.json | 4 +- .../Controllers/EventController.cs | 2 +- .../Controllers/OrganizationController.cs | 3 +- .../Controllers/ProjectController.cs | 6 +- .../Controllers/StackController.cs | 2 +- .../Controllers/TokenController.cs | 5 +- .../Controllers/UserController.cs | 4 +- .../Controllers/WebHookController.cs | 3 +- .../Exceptionless.Web.csproj | 1 - src/Exceptionless.Web/Startup.cs | 4 +- ...veProblemJsonFromSuccessResponsesFilter.cs | 40 + .../Utility/XEnumNamesSchemaFilter.cs | 37 + .../Controllers/Data/swagger.json | 14731 ++++++++-------- .../Controllers/OpenApiControllerTests.cs | 11 +- 15 files changed, 7182 insertions(+), 7675 deletions(-) create mode 100644 src/Exceptionless.Web/Utility/RemoveProblemJsonFromSuccessResponsesFilter.cs create mode 100644 src/Exceptionless.Web/Utility/XEnumNamesSchemaFilter.cs diff --git a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj index 9ee1cf456e..2d5acf37e0 100644 --- a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj +++ b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj @@ -22,10 +22,6 @@ - - - - diff --git a/src/Exceptionless.Web/ClientApp/package.json b/src/Exceptionless.Web/ClientApp/package.json index bd93c6a03d..d3694db6eb 100644 --- a/src/Exceptionless.Web/ClientApp/package.json +++ b/src/Exceptionless.Web/ClientApp/package.json @@ -15,7 +15,7 @@ "format": "npm run format:prettier && npm run format:eslint", "format:eslint": "eslint . --fix --concurrency=auto", "format:prettier": "prettier --write .", - "generate-models": "swagger-typescript-api -p http://localhost:5200/docs/v2/swagger.json -o ./src/lib/generated -n api.ts --no-client --templates api-templates", + "generate-models": "swagger-typescript-api generate -p http://localhost:5200/docs/v2/swagger.json -o ./src/lib/generated -n api.ts --no-client --templates api-templates", "generate-templates": "swagger-typescript-api generate-templates -o api-templates", "test:e2e": "playwright test", "test:unit": "vitest run", @@ -100,4 +100,4 @@ "overrides": { "storybook": "$storybook" } -} +} \ No newline at end of file diff --git a/src/Exceptionless.Web/Controllers/EventController.cs b/src/Exceptionless.Web/Controllers/EventController.cs index e09f9e38e1..08713d9da3 100644 --- a/src/Exceptionless.Web/Controllers/EventController.cs +++ b/src/Exceptionless.Web/Controllers/EventController.cs @@ -1350,7 +1350,7 @@ await _eventPostService.EnqueueAsync(new EventPost(_appOptions.EnableArchive) /// An error occurred while deleting one or more event occurrences. [HttpDelete("{ids:objectids}")] [Authorize(Policy = AuthorizationRoles.UserPolicy)] - [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status202Accepted)] public Task> DeleteAsync(string ids) { return DeleteImplAsync(ids.FromDelimitedString()); diff --git a/src/Exceptionless.Web/Controllers/OrganizationController.cs b/src/Exceptionless.Web/Controllers/OrganizationController.cs index 4a2bb3d182..05e2bc7e33 100644 --- a/src/Exceptionless.Web/Controllers/OrganizationController.cs +++ b/src/Exceptionless.Web/Controllers/OrganizationController.cs @@ -144,6 +144,7 @@ public async Task> GetAsync(string id, string? mo /// The organization already exists. [HttpPost] [Consumes("application/json")] + [ProducesResponseType(StatusCodes.Status201Created)] public Task> PostAsync(NewOrganization organization) { return PostImplAsync(organization); @@ -175,7 +176,7 @@ public Task> PatchAsync(string id, DeltaAn error occurred while deleting one or more organizations. [HttpDelete] [Route("{ids:objectids}")] - [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status202Accepted)] public Task> DeleteAsync(string ids) { return DeleteImplAsync(ids.FromDelimitedString()); diff --git a/src/Exceptionless.Web/Controllers/ProjectController.cs b/src/Exceptionless.Web/Controllers/ProjectController.cs index e61a7c328e..3f55ec31e5 100644 --- a/src/Exceptionless.Web/Controllers/ProjectController.cs +++ b/src/Exceptionless.Web/Controllers/ProjectController.cs @@ -157,7 +157,7 @@ public async Task> GetAsync(string id, string? mode = [HttpPost] [Consumes("application/json")] [Authorize(Policy = AuthorizationRoles.UserPolicy)] - [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status201Created)] public Task> PostAsync(NewProject project) { return PostImplAsync(project); @@ -189,7 +189,7 @@ public Task> PatchAsync(string id, DeltaAn error occurred while deleting one or more projects. [HttpDelete("{ids:objectids}")] [Authorize(Policy = AuthorizationRoles.UserPolicy)] - [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status202Accepted)] public Task> DeleteAsync(string ids) { return DeleteImplAsync(ids.FromDelimitedString()); @@ -318,7 +318,7 @@ public async Task DeleteConfigAsync(string id, string key) /// The project could not be found. [HttpGet("{id:objectid}/reset-data")] [Authorize(Policy = AuthorizationRoles.UserPolicy)] - [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status202Accepted)] public async Task> ResetDataAsync(string id) { var project = await GetModelAsync(id); diff --git a/src/Exceptionless.Web/Controllers/StackController.cs b/src/Exceptionless.Web/Controllers/StackController.cs index 8a3883b100..1a0a9021c7 100644 --- a/src/Exceptionless.Web/Controllers/StackController.cs +++ b/src/Exceptionless.Web/Controllers/StackController.cs @@ -441,7 +441,7 @@ await _webHookNotificationQueue.EnqueueAsync(new WebHookNotification /// An error occurred while deleting one or more stacks. [HttpDelete("{ids:objectids}")] [Authorize(Policy = AuthorizationRoles.UserPolicy)] - [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status202Accepted)] public Task> DeleteAsync(string ids) { return DeleteImplAsync(ids.FromDelimitedString()); diff --git a/src/Exceptionless.Web/Controllers/TokenController.cs b/src/Exceptionless.Web/Controllers/TokenController.cs index 9ffcf55e21..f45afccbbb 100644 --- a/src/Exceptionless.Web/Controllers/TokenController.cs +++ b/src/Exceptionless.Web/Controllers/TokenController.cs @@ -127,6 +127,7 @@ public async Task> GetAsync(string id) /// The token already exists. [HttpPost] [Consumes("application/json")] + [ProducesResponseType(StatusCodes.Status201Created)] public async Task> PostAsync(NewToken token) { if (User.IsTokenAuthType()) @@ -149,6 +150,7 @@ public async Task> PostAsync(NewToken token) /// The token already exists. [HttpPost("~/" + API_PREFIX + "/projects/{projectId:objectid}/tokens")] [Consumes("application/json")] + [ProducesResponseType(StatusCodes.Status201Created)] public async Task> PostByProjectAsync(string projectId, NewToken? token = null) { if (User.IsTokenAuthType()) @@ -179,6 +181,7 @@ public async Task> PostByProjectAsync(string projectId, /// The token already exists. [HttpPost("~/" + API_PREFIX + "/organizations/{organizationId:objectid}/tokens")] [Consumes("application/json")] + [ProducesResponseType(StatusCodes.Status201Created)] public async Task> PostByOrganizationAsync(string organizationId, NewToken? token = null) { if (User.IsTokenAuthType()) @@ -221,7 +224,7 @@ public async Task> PatchAsync(string id, DeltaOne or more tokens were not found. /// An error occurred while deleting one or more tokens. [HttpDelete("{ids:tokens}")] - [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status202Accepted)] public async Task> DeleteAsync(string ids) { if (User.IsTokenAuthType()) diff --git a/src/Exceptionless.Web/Controllers/UserController.cs b/src/Exceptionless.Web/Controllers/UserController.cs index afdcd9248c..e52dcba5eb 100644 --- a/src/Exceptionless.Web/Controllers/UserController.cs +++ b/src/Exceptionless.Web/Controllers/UserController.cs @@ -128,7 +128,7 @@ public Task> PatchAsync(string id, Delta chan /// /// The current user could not be found. [HttpDelete("me")] - [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status202Accepted)] public Task> DeleteCurrentUserAsync() { string[] userIds = !String.IsNullOrEmpty(CurrentUser.Id) ? [CurrentUser.Id] : []; @@ -145,7 +145,7 @@ public Task> DeleteCurrentUserAsync() /// An error occurred while deleting one or more users. [HttpDelete("{ids:objectids}")] [Authorize(Policy = AuthorizationRoles.GlobalAdminPolicy)] - [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status202Accepted)] public Task> DeleteAsync(string ids) { return DeleteImplAsync(ids.FromDelimitedString()); diff --git a/src/Exceptionless.Web/Controllers/WebHookController.cs b/src/Exceptionless.Web/Controllers/WebHookController.cs index 5f0519f5ff..72d2e9170b 100644 --- a/src/Exceptionless.Web/Controllers/WebHookController.cs +++ b/src/Exceptionless.Web/Controllers/WebHookController.cs @@ -73,6 +73,7 @@ public Task> GetAsync(string id) [HttpPost] [Consumes("application/json")] [Authorize(Policy = AuthorizationRoles.UserPolicy)] + [ProducesResponseType(StatusCodes.Status201Created)] public Task> PostAsync(NewWebHook webhook) { return PostImplAsync(webhook); @@ -88,7 +89,7 @@ public Task> PostAsync(NewWebHook webhook) /// An error occurred while deleting one or more web hooks. [HttpDelete("{ids:objectids}")] [Authorize(Policy = AuthorizationRoles.UserPolicy)] - [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status202Accepted)] public Task> DeleteAsync(string ids) { return DeleteImplAsync(ids.FromDelimitedString()); diff --git a/src/Exceptionless.Web/Exceptionless.Web.csproj b/src/Exceptionless.Web/Exceptionless.Web.csproj index af79fd1463..354b9eb571 100644 --- a/src/Exceptionless.Web/Exceptionless.Web.csproj +++ b/src/Exceptionless.Web/Exceptionless.Web.csproj @@ -35,7 +35,6 @@ - diff --git a/src/Exceptionless.Web/Startup.cs b/src/Exceptionless.Web/Startup.cs index 41885463eb..fb287c7b2e 100644 --- a/src/Exceptionless.Web/Startup.cs +++ b/src/Exceptionless.Web/Startup.cs @@ -26,7 +26,6 @@ using Newtonsoft.Json; using Serilog; using Serilog.Events; -using Unchase.Swashbuckle.AspNetCore.Extensions.Extensions; namespace Exceptionless.Web; @@ -148,8 +147,9 @@ public void ConfigureServices(IServiceCollection services) c.IgnoreObsoleteActions(); c.OperationFilter(); + c.SchemaFilter(); + c.DocumentFilter(); - c.AddEnumsWithValuesFixFilters(); c.SupportNonNullableReferenceTypes(); }); services.AddSwaggerGenNewtonsoftSupport(); diff --git a/src/Exceptionless.Web/Utility/RemoveProblemJsonFromSuccessResponsesFilter.cs b/src/Exceptionless.Web/Utility/RemoveProblemJsonFromSuccessResponsesFilter.cs new file mode 100644 index 0000000000..d3b0983f0a --- /dev/null +++ b/src/Exceptionless.Web/Utility/RemoveProblemJsonFromSuccessResponsesFilter.cs @@ -0,0 +1,40 @@ +using Microsoft.OpenApi; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace Exceptionless.Web.Utility; + +/// +/// Removes application/problem+json content type from successful (2xx) responses. +/// The problem+json media type (RFC 7807) should only be used for error responses. +/// +public class RemoveProblemJsonFromSuccessResponsesFilter : IDocumentFilter +{ + private const string ProblemJsonContentType = "application/problem+json"; + + public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) + { + if (swaggerDoc.Paths is null) + return; + + foreach (var path in swaggerDoc.Paths) + { + if (path.Value?.Operations is null) + continue; + + foreach (var operation in path.Value.Operations.Values) + { + if (operation?.Responses is null) + continue; + + foreach (var response in operation.Responses) + { + // Only process 2xx success responses + if (response.Key.StartsWith('2') && response.Value?.Content is not null) + { + response.Value.Content.Remove(ProblemJsonContentType); + } + } + } + } + } +} diff --git a/src/Exceptionless.Web/Utility/XEnumNamesSchemaFilter.cs b/src/Exceptionless.Web/Utility/XEnumNamesSchemaFilter.cs new file mode 100644 index 0000000000..b1594a49e6 --- /dev/null +++ b/src/Exceptionless.Web/Utility/XEnumNamesSchemaFilter.cs @@ -0,0 +1,37 @@ +using System.Text.Json.Nodes; +using Microsoft.OpenApi; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace Exceptionless.Web.Utility; + +/// +/// Schema filter that adds x-enumNames extension to numeric enum schemas. +/// This enables swagger-typescript-api and similar generators to create +/// meaningful enum member names instead of Value0, Value1, etc. +/// +public class XEnumNamesSchemaFilter : ISchemaFilter +{ + public void Apply(IOpenApiSchema schema, SchemaFilterContext context) + { + if (schema is not OpenApiSchema concrete) + return; + + var type = context.Type; + if (type is null || !type.IsEnum) + return; + + if (concrete.Enum is null || concrete.Enum.Count == 0) + return; + + var names = Enum.GetNames(type); + var enumNamesArray = new JsonArray(); + + foreach (var name in names) + { + enumNamesArray.Add(name); + } + + concrete.Extensions ??= new Dictionary(); + concrete.Extensions["x-enumNames"] = new JsonNodeExtension(enumNamesArray); + } +} diff --git a/tests/Exceptionless.Tests/Controllers/Data/swagger.json b/tests/Exceptionless.Tests/Controllers/Data/swagger.json index 1b5fe4ba62..6bc77c2765 100644 --- a/tests/Exceptionless.Tests/Controllers/Data/swagger.json +++ b/tests/Exceptionless.Tests/Controllers/Data/swagger.json @@ -1,7800 +1,7225 @@ { - "openapi": "3.0.4", - "info": { - "title": "Exceptionless API", - "termsOfService": "https://exceptionless.com/terms/", - "contact": { - "name": "Exceptionless", - "url": "https://github.com/exceptionless/Exceptionless", - "email": "" - }, - "license": { - "name": "Apache License 2.0", - "url": "https://github.com/exceptionless/Exceptionless/blob/main/LICENSE.txt" + "openapi": "3.0.4", + "info": { + "title": "Exceptionless API", + "termsOfService": "https://exceptionless.com/terms/", + "contact": { + "name": "Exceptionless", + "url": "https://github.com/exceptionless/Exceptionless", + "email": "" + }, + "license": { + "name": "Apache License 2.0", + "url": "https://github.com/exceptionless/Exceptionless/blob/main/LICENSE.txt" + }, + "version": "v2" }, - "version": "v2" - }, - "paths": { - "/api/v2/auth/login": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Login", - "description": "Log in with your email address and password to generate a token scoped with your users roles.\n \n```{ \"email\": \"noreply@exceptionless.io\", \"password\": \"exceptionless\" }```\n \nThis token can then be used to access the api. You can use this token in the header (bearer authentication)\nor append it onto the query string: ?access_token=MY_TOKEN\n \nPlease note that you can also use this token on the documentation site by placing it in the\nheaders api_key input box.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Login" - } + "paths": { + "/api/v2/auth/login": { + "post": { + "tags": ["Auth"], + "summary": "Login", + "description": "Log in with your email address and password to generate a token scoped with your users roles.\n \n```{ \"email\": \"noreply@exceptionless.io\", \"password\": \"exceptionless\" }```\n \nThis token can then be used to access the api. You can use this token in the header (bearer authentication)\nor append it onto the query string: ?access_token=MY_TOKEN\n \nPlease note that you can also use this token on the documentation site by placing it in the\nheaders api_key input box.", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Login" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "401": { + "description": "Login failed" + }, + "422": { + "description": "Validation error" + } + } } - } }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + "/api/v2/auth/logout": { + "get": { + "tags": ["Auth"], + "summary": "Logout the current user and remove the current access token", + "responses": { + "200": { + "description": "User successfully logged-out" + }, + "401": { + "description": "User not logged in" + }, + "403": { + "description": "Current action is not supported with user access token" + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "401": { - "description": "Login failed" - }, - "422": { - "description": "Validation error" - } - } - } - }, - "/api/v2/auth/logout": { - "get": { - "tags": [ - "Auth" - ], - "summary": "Logout the current user and remove the current access token", - "responses": { - "200": { - "description": "User successfully logged-out" - }, - "401": { - "description": "User not logged in" - }, - "403": { - "description": "Current action is not supported with user access token" - } - } - } - }, - "/api/v2/auth/signup": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Sign up", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Signup" - } } - } }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + "/api/v2/auth/signup": { + "post": { + "tags": ["Auth"], + "summary": "Sign up", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Signup" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "401": { + "description": "Sign-up failed" + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "401": { - "description": "Sign-up failed" - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } - } - } - }, - "/api/v2/auth/github": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Sign in with GitHub", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalAuthInfo" - } } - } }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + "/api/v2/auth/github": { + "post": { + "tags": ["Auth"], + "summary": "Sign in with GitHub", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + } + }, + "/api/v2/auth/google": { + "post": { + "tags": ["Auth"], + "summary": "Sign in with Google", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } } - } } - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } - } - } - }, - "/api/v2/auth/google": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Sign in with Google", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalAuthInfo" - } + }, + "/api/v2/auth/facebook": { + "post": { + "tags": ["Auth"], + "summary": "Sign in with Facebook", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } } - } }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + "/api/v2/auth/live": { + "post": { + "tags": ["Auth"], + "summary": "Sign in with Microsoft", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + } + }, + "/api/v2/auth/unlink/{providerName}": { + "post": { + "tags": ["Auth"], + "summary": "Removes an external login provider from the account", + "parameters": [ + { + "name": "providerName", + "in": "path", + "description": "The provider name.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "The provider user id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "400": { + "description": "Invalid provider name." + } } - } } - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } - } - } - }, - "/api/v2/auth/facebook": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Sign in with Facebook", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalAuthInfo" - } + }, + "/api/v2/auth/change-password": { + "post": { + "tags": ["Auth"], + "summary": "Change password", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChangePasswordModel" + } + } + } + }, + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" + } + } + } + }, + "422": { + "description": "Validation error" + } + } } - } }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + "/api/v2/auth/forgot-password/{email}": { + "get": { + "tags": ["Auth"], + "summary": "Forgot password", + "parameters": [ + { + "name": "email", + "in": "path", + "description": "The email address.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Forgot password email was sent." + }, + "400": { + "description": "Invalid email address." + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + } + }, + "/api/v2/auth/reset-password": { + "post": { + "tags": ["Auth"], + "summary": "Reset password", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPasswordModel" + } + } + } + }, + "responses": { + "200": { + "description": "Password reset email was sent." + }, + "422": { + "description": "Invalid reset password model." + } } - } } - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } - } - } - }, - "/api/v2/auth/live": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Sign in with Microsoft", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalAuthInfo" - } + }, + "/api/v2/auth/cancel-reset-password/{token}": { + "post": { + "tags": ["Auth"], + "summary": "Cancel reset password", + "parameters": [ + { + "name": "token", + "in": "path", + "description": "The password reset token.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Password reset email was cancelled." + }, + "400": { + "description": "Invalid password reset token." + } + } } - } }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + "/api/v2/events/count": { + "get": { + "tags": ["Event"], + "summary": "Count", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "aggregations", + "in": "query", + "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CountResult" + } + } + } + }, + "400": { + "description": "Invalid filter." + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + } + }, + "/api/v2/organizations/{organizationId}/events/count": { + "get": { + "tags": ["Event"], + "summary": "Count by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "aggregations", + "in": "query", + "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CountResult" + } + } + } + }, + "400": { + "description": "Invalid filter." + } } - } } - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } - } - } - }, - "/api/v2/auth/unlink/{providerName}": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Removes an external login provider from the account", - "parameters": [ - { - "name": "providerName", - "in": "path", - "description": "The provider name.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" + }, + "/api/v2/projects/{projectId}/events/count": { + "get": { + "tags": ["Event"], + "summary": "Count by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "aggregations", + "in": "query", + "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If mode is set to stack_new, then additional filters will be added.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CountResult" + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } } - } - ], - "requestBody": { - "description": "The provider user id.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } + }, + "/api/v2/events/{id}": { + "get": { + "tags": ["Event"], + "summary": "Get by id", + "operationId": "GetPersistentEventById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the event.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + }, + "404": { + "description": "The event occurrence could not be found." + }, + "426": { + "description": "Unable to view event occurrence due to plan limits." + } + } } - } }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + "/api/v2/events": { + "get": { + "tags": ["Event"], + "summary": "Get all", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + }, + "post": { + "tags": ["Event"], + "summary": "Submit event by POST", + "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", + "parameters": [ + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "string", + "example": "" + } + }, + "text/plain": { + "schema": { + "type": "string", + "example": "" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } } - } } - }, - "400": { - "description": "Invalid provider name." - } - } - } - }, - "/api/v2/auth/change-password": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Change password", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ChangePasswordModel" - } + }, + "/api/v2/organizations/{organizationId}/events": { + "get": { + "tags": ["Event"], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The organization could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } } - } }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + "/api/v2/projects/{projectId}/events": { + "get": { + "tags": ["Event"], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" + }, + "post": { + "tags": ["Event"], + "summary": "Submit event by POST for a specific project", + "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "string", + "example": "" + } + }, + "text/plain": { + "schema": { + "type": "string", + "example": "" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } } - } } - }, - "422": { - "description": "Validation error" - } - } - } - }, - "/api/v2/auth/forgot-password/{email}": { - "get": { - "tags": [ - "Auth" - ], - "summary": "Forgot password", - "parameters": [ - { - "name": "email", - "in": "path", - "description": "The email address.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" + }, + "/api/v2/stacks/{stackId}/events": { + "get": { + "tags": ["Event"], + "summary": "Get by stack", + "parameters": [ + { + "name": "stackId", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The stack could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } } - } - ], - "responses": { - "200": { - "description": "Forgot password email was sent." - }, - "400": { - "description": "Invalid email address." - } - } - } - }, - "/api/v2/auth/reset-password": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Reset password", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ResetPasswordModel" - } + }, + "/api/v2/events/by-ref/{referenceId}": { + "get": { + "tags": ["Event"], + "summary": "Get by reference id", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } } - } }, - "responses": { - "200": { - "description": "Password reset email was sent." - }, - "422": { - "description": "Invalid reset password model." - } - } - } - }, - "/api/v2/auth/cancel-reset-password/{token}": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Cancel reset password", - "parameters": [ - { - "name": "token", - "in": "path", - "description": "The password reset token.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" + "/api/v2/projects/{projectId}/events/by-ref/{referenceId}": { + "get": { + "tags": ["Event"], + "summary": "Get by reference id", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } } - } - ], - "responses": { - "200": { - "description": "Password reset email was cancelled." - }, - "400": { - "description": "Invalid password reset token." - } - } - } - }, - "/api/v2/events/count": { - "get": { - "tags": [ - "Event" - ], - "summary": "Count", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" + }, + "/api/v2/events/sessions/{sessionId}": { + "get": { + "tags": ["Event"], + "summary": "Get a list of all sessions or events by a session id", + "parameters": [ + { + "name": "sessionId", + "in": "path", + "description": "An identifier that represents a session of events.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } } - }, - { - "name": "aggregations", - "in": "query", - "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", - "schema": { - "type": "string" + }, + "/api/v2/projects/{projectId}/events/sessions/{sessionId}": { + "get": { + "tags": ["Event"], + "summary": "Get a list of by a session id", + "parameters": [ + { + "name": "sessionId", + "in": "path", + "description": "An identifier that represents a session of events.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" + }, + "/api/v2/events/sessions": { + "get": { + "tags": ["Event"], + "summary": "Get a list of all sessions", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" + }, + "/api/v2/organizations/{organizationId}/events/sessions": { + "get": { + "tags": ["Event"], + "summary": "Get a list of all sessions", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{projectId}/events/sessions": { + "get": { + "tags": ["Event"], + "summary": "Get a list of all sessions", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CountResult" + }, + "/api/v2/events/by-ref/{referenceId}/user-description": { + "post": { + "tags": ["Event"], + "summary": "Set user description", + "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The user description.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserDescription" + } + } + } + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "Description must be specified." + }, + "404": { + "description": "The event occurrence with the specified reference id could not be found." + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/CountResult" + } + }, + "/api/v2/projects/{projectId}/events/by-ref/{referenceId}/user-description": { + "post": { + "tags": ["Event"], + "summary": "Set user description", + "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The user description.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserDescription" + } + } + } + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "Description must be specified." + }, + "404": { + "description": "The event occurrence with the specified reference id could not be found." + } } - } } - }, - "400": { - "description": "Invalid filter." - } - } - } - }, - "/api/v2/organizations/{organizationId}/events/count": { - "get": { - "tags": [ - "Event" - ], - "summary": "Count by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" + }, + "/api/v2/events/session/heartbeat": { + "get": { + "tags": ["Event"], + "summary": "Submit heartbeat", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "The session id or user id.", + "schema": { + "type": "string" + } + }, + { + "name": "close", + "in": "query", + "description": "If true, the session will be closed.", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" + }, + "/api/v2/events/submit": { + "get": { + "tags": ["Event"], + "summary": "Submit event by GET", + "description": "You can submit an event using an HTTP GET and query string parameters. Any unknown query string parameters will be added to the extended data of the event.\n \nFeature usage named build with a duration of 10:\n```/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "type", + "in": "query", + "description": "The event type (ie. error, log message, feature usage).", + "schema": { + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query string parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } } - }, - { - "name": "aggregations", - "in": "query", - "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", - "schema": { - "type": "string" + }, + "/api/v2/events/submit/{type}": { + "get": { + "tags": ["Event"], + "summary": "Submit event type by GET", + "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage event named build with a value of 10:\n```/events/submit/usage?access_token=YOUR_API_KEY&source=build&value=10```\n \nLog event with message, geo and extended data\n```/events/submit/log?access_token=YOUR_API_KEY&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "type", + "in": "path", + "description": "The event type (ie. error, log message, feature usage).", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query string parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{projectId}/events/submit": { + "get": { + "tags": ["Event"], + "summary": "Submit event type by GET for a specific project", + "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query String parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{projectId}/events/submit/{type}": { + "get": { + "tags": ["Event"], + "summary": "Submit event type by GET for a specific project", + "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "type", + "in": "path", + "description": "The event type (ie. error, log message, feature usage).", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query String parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" + }, + "/api/v2/events/{ids}": { + "delete": { + "tags": ["Event"], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of event identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more event occurrences were not found." + }, + "500": { + "description": "An error occurred while deleting one or more event occurrences." + } + } } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CountResult" + }, + "/api/v2/organizations": { + "get": { + "tags": ["Organization"], + "summary": "Get all", + "parameters": [ + { + "name": "mode", + "in": "query", + "description": "If no mode is set then a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + } + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/CountResult" + }, + "post": { + "tags": ["Organization"], + "summary": "Create", + "requestBody": { + "description": "The organization.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewOrganization" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "400": { + "description": "An error occurred while creating the organization." + }, + "409": { + "description": "The organization already exists." + } } - } } - }, - "400": { - "description": "Invalid filter." - } - } - } - }, - "/api/v2/projects/{projectId}/events/count": { - "get": { - "tags": [ - "Event" - ], - "summary": "Count by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" + }, + "/api/v2/organizations/{id}": { + "get": { + "tags": ["Organization"], + "summary": "Get by id", + "operationId": "GetOrganizationById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + }, + "patch": { + "tags": ["Organization"], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "400": { + "description": "An error occurred while updating the organization." + }, + "404": { + "description": "The organization could not be found." + } + } + }, + "put": { + "tags": ["Organization"], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "400": { + "description": "An error occurred while updating the organization." + }, + "404": { + "description": "The organization could not be found." + } + } } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" + }, + "/api/v2/organizations/{ids}": { + "delete": { + "tags": ["Organization"], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of organization identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more organizations were not found." + }, + "500": { + "description": "An error occurred while deleting one or more organizations." + } + } } - }, - { - "name": "aggregations", - "in": "query", - "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", - "schema": { - "type": "string" + }, + "/api/v2/organizations/invoice/{id}": { + "get": { + "tags": ["Organization"], + "summary": "Get invoice", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the invoice.", + "required": true, + "schema": { + "minLength": 10, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Invoice" + } + } + } + }, + "404": { + "description": "The invoice was not found." + } + } } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" + }, + "/api/v2/organizations/{id}/invoices": { + "get": { + "tags": ["Organization"], + "summary": "Get invoices", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "before", + "in": "query", + "description": "A cursor for use in pagination. before is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, starting with obj_bar, your subsequent call can include before=obj_bar in order to fetch the previous page of the list.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "A cursor for use in pagination. after is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include after=obj_foo in order to fetch the next page of the list.", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 12 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InvoiceGridModel" + } + } + } + } + }, + "404": { + "description": "The organization was not found." + } + } } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" + }, + "/api/v2/organizations/{id}/plans": { + "get": { + "tags": ["Organization"], + "summary": "Get plans", + "description": "Gets available plans for a specific organization.", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BillingPlan" + } + } + } + } + }, + "404": { + "description": "The organization was not found." + } + } } - }, - { - "name": "mode", - "in": "query", - "description": "If mode is set to stack_new, then additional filters will be added.", - "schema": { - "type": "string" + }, + "/api/v2/organizations/{id}/change-plan": { + "post": { + "tags": ["Organization"], + "summary": "Change plan", + "description": "Upgrades or downgrades the organizations plan.", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "planId", + "in": "query", + "description": "The identifier of the plan.", + "schema": { + "type": "string" + } + }, + { + "name": "stripeToken", + "in": "query", + "description": "The token returned from the stripe service.", + "schema": { + "type": "string" + } + }, + { + "name": "last4", + "in": "query", + "description": "The last four numbers of the card.", + "schema": { + "type": "string" + } + }, + { + "name": "couponId", + "in": "query", + "description": "The coupon id.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChangePlanResult" + } + } + } + }, + "404": { + "description": "The organization was not found." + } + } } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CountResult" + }, + "/api/v2/organizations/{id}/users/{email}": { + "post": { + "tags": ["Organization"], + "summary": "Add user", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "email", + "in": "path", + "description": "The email address of the user you wish to add to your organization.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "404": { + "description": "The organization was not found." + }, + "426": { + "description": "Please upgrade your plan to add an additional user." + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/CountResult" + }, + "delete": { + "tags": ["Organization"], + "summary": "Remove user", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "email", + "in": "path", + "description": "The email address of the user you wish to remove from your organization.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "The error occurred while removing the user from your organization" + }, + "404": { + "description": "The organization was not found." + } } - } - } - }, - "400": { - "description": "Invalid filter." - } - } - } - }, - "/api/v2/events/{id}": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get by id", - "operationId": "GetPersistentEventById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the event.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PersistentEvent" + }, + "/api/v2/organizations/{id}/data/{key}": { + "post": { + "tags": ["Organization"], + "summary": "Add custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "path", + "description": "The key name of the data object.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "Any string value.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The organization was not found." + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/PersistentEvent" + }, + "delete": { + "tags": ["Organization"], + "summary": "Remove custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "path", + "description": "The key name of the data object.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The organization was not found." + } } - } - } - }, - "404": { - "description": "The event occurrence could not be found." - }, - "426": { - "description": "Unable to view event occurrence due to plan limits." - } - } - } - }, - "/api/v2/events": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get all", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" + }, + "/api/v2/organizations/check-name": { + "get": { + "tags": ["Organization"], + "summary": "Check for unique name", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "The organization name to check.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "201": { + "description": "The organization name is available." + }, + "204": { + "description": "The organization name is not available." + } + } } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" + }, + "/api/v2/projects": { + "get": { + "tags": ["Project"], + "summary": "Get all", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + } + } + } + }, + "post": { + "tags": ["Project"], + "summary": "Create", + "requestBody": { + "description": "The project.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewProject" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "400": { + "description": "An error occurred while creating the project." + }, + "409": { + "description": "The project already exists." + } + } } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" + }, + "/api/v2/organizations/{organizationId}/projects": { + "get": { + "tags": ["Project"], + "summary": "Get all", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 + }, + "/api/v2/projects/{id}": { + "get": { + "tags": ["Project"], + "summary": "Get by id", + "operationId": "GetProjectById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + }, + "patch": { + "tags": ["Project"], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "400": { + "description": "An error occurred while updating the project." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "put": { + "tags": ["Project"], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "400": { + "description": "An error occurred while updating the project." + }, + "404": { + "description": "The project could not be found." + } + } } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{ids}": { + "delete": { + "tags": ["Project"], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of project identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more projects were not found." + }, + "500": { + "description": "An error occurred while deleting one or more projects." + } + } } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" + }, + "/api/v2/projects/config": { + "get": { + "tags": ["Project"], + "summary": "Get configuration settings", + "parameters": [ + { + "name": "v", + "in": "query", + "description": "The client configuration version.", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ClientConfiguration" + } + } + } + }, + "304": { + "description": "The client configuration version is the current version." + }, + "404": { + "description": "The project could not be found." + } + } } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } + }, + "/api/v2/projects/{id}/config": { + "get": { + "tags": ["Project"], + "summary": "Get configuration settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "v", + "in": "query", + "description": "The client configuration version.", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ClientConfiguration" + } + } + } + }, + "304": { + "description": "The client configuration version is the current version." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": ["Project"], + "summary": "Add configuration value", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the configuration object.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "The configuration value.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid configuration value." + }, + "404": { + "description": "The project could not be found." + } } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } + }, + "delete": { + "tags": ["Project"], + "summary": "Remove configuration value", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the configuration object.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid key value." + }, + "404": { + "description": "The project could not be found." + } } - } } - }, - "400": { - "description": "Invalid filter." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - }, - "post": { - "tags": [ - "Event" - ], - "summary": "Submit event by POST", - "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", - "parameters": [ - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{id}/reset-data": { + "get": { + "tags": ["Project"], + "summary": "Reset project data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "string", - "example": "" - } + }, + "/api/v2/users/{userId}/projects/{id}/notifications": { + "get": { + "tags": ["Project"], + "summary": "Get user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } }, - "text/plain": { - "schema": { - "type": "string", - "example": "" - } + "put": { + "tags": ["Project"], + "summary": "Set user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": ["Project"], + "summary": "Set user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": ["Project"], + "summary": "Remove user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project could not be found." + } + } } - }, - "required": true }, - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } - } - }, - "/api/v2/organizations/{organizationId}/events": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" + "/api/v2/projects/{id}/{integration}/notifications": { + "put": { + "tags": ["Project"], + "summary": "Set an integrations notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "integration", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project or integration could not be found." + }, + "426": { + "description": "Please upgrade your plan to enable integrations." + } + } + }, + "post": { + "tags": ["Project"], + "summary": "Set an integrations notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "integration", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project or integration could not be found." + }, + "426": { + "description": "Please upgrade your plan to enable integrations." + } + } } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{id}/promotedtabs": { + "put": { + "tags": ["Project"], + "summary": "Promote tab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "The tab name.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid tab name." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": ["Project"], + "summary": "Promote tab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "The tab name.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid tab name." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": ["Project"], + "summary": "Demote tab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "The tab name.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid tab name." + }, + "404": { + "description": "The project could not be found." + } + } } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" + }, + "/api/v2/projects/check-name": { + "get": { + "tags": ["Project"], + "summary": "Check for unique name", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "The project name to check.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "The project name is available." + }, + "204": { + "description": "The project name is not available." + } + } } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" + }, + "/api/v2/organizations/{organizationId}/projects/check-name": { + "get": { + "tags": ["Project"], + "summary": "Check for unique name", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "The project name to check.", + "schema": { + "type": "string" + } + }, + { + "name": "organizationId", + "in": "path", + "description": "If set the check name will be scoped to a specific organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "The project name is available." + }, + "204": { + "description": "The project name is not available." + } + } } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{id}/data": { + "post": { + "tags": ["Project"], + "summary": "Add custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the data object.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Any string value.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid key or value." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": ["Project"], + "summary": "Remove custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the data object.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid key or value." + }, + "404": { + "description": "The project could not be found." + } + } } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" + }, + "/api/v2/stacks/{id}": { + "get": { + "tags": ["Stack"], + "summary": "Get by id", + "operationId": "GetStackById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the `time` filter. This is used for time zone support.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Stack" + } + } + } + }, + "404": { + "description": "The stack could not be found." + } + } } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" + }, + "/api/v2/stacks/{ids}/mark-fixed": { + "post": { + "tags": ["Stack"], + "summary": "Mark fixed", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + }, + { + "name": "version", + "in": "query", + "description": "A version number that the stack was fixed in.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "404": { + "description": "One or more stacks could not be found." + } + } } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 + }, + "/api/v2/stacks/{ids}/mark-snoozed": { + "post": { + "tags": ["Stack"], + "summary": "Mark the selected stacks as snoozed", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + }, + { + "name": "snoozeUntilUtc", + "in": "query", + "description": "A time that the stack should be snoozed until.", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "404": { + "description": "One or more stacks could not be found." + } + } } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" + }, + "/api/v2/stacks/{id}/add-link": { + "post": { + "tags": ["Stack"], + "summary": "Add reference link", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The reference link.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid reference link." + }, + "404": { + "description": "The stack could not be found." + } + } } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" + }, + "/api/v2/stacks/{id}/remove-link": { + "post": { + "tags": ["Stack"], + "summary": "Remove reference link", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The reference link.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "204": { + "description": "The reference link was removed." + }, + "400": { + "description": "Invalid reference link." + }, + "404": { + "description": "The stack could not be found." + } + } } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } + }, + "/api/v2/stacks/{ids}/mark-critical": { + "post": { + "tags": ["Stack"], + "summary": "Mark future occurrences as critical", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "One or more stacks could not be found." + } } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } + }, + "delete": { + "tags": ["Stack"], + "summary": "Mark future occurrences as not critical", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The stacks were marked as not critical." + }, + "404": { + "description": "One or more stacks could not be found." + } } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The organization could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - } - }, - "/api/v2/projects/{projectId}/events": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" + }, + "/api/v2/stacks/{ids}/change-status": { + "post": { + "tags": ["Stack"], + "summary": "Change stack status", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "The status that the stack should be changed to.", + "schema": { + "$ref": "#/components/schemas/StackStatus" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "One or more stacks could not be found." + } + } } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" + }, + "/api/v2/stacks/{id}/promote": { + "post": { + "tags": ["Stack"], + "summary": "Promote to external service", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The stack could not be found." + }, + "426": { + "description": "Promote to External is a premium feature used to promote an error stack to an external system." + }, + "501": { + "description": "No promoted web hooks are configured for this project." + } + } } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" + }, + "/api/v2/stacks/{ids}": { + "delete": { + "tags": ["Stack"], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more stacks were not found." + }, + "500": { + "description": "An error occurred while deleting one or more stacks." + } + } } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" + }, + "/api/v2/stacks": { + "get": { + "tags": ["Stack"], + "summary": "Get all", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" + }, + "/api/v2/organizations/{organizationId}/stacks": { + "get": { + "tags": ["Stack"], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The organization could not be found." + }, + "426": { + "description": "Unable to view stack occurrences for the suspended organization." + } + } } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" + }, + "/api/v2/projects/{projectId}/stacks": { + "get": { + "tags": ["Stack"], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The organization could not be found." + }, + "426": { + "description": "Unable to view stack occurrences for the suspended organization." + } + } } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 + }, + "/api/v2/organizations/{organizationId}/tokens": { + "get": { + "tags": ["Token"], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + }, + "post": { + "tags": ["Token"], + "summary": "Create for organization", + "description": "This is a helper action that makes it easier to create a token for a specific organization.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewToken" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while creating the token." + }, + "409": { + "description": "The token already exists." + } + } } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{projectId}/tokens": { + "get": { + "tags": ["Token"], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": ["Token"], + "summary": "Create for project", + "description": "This is a helper action that makes it easier to create a token for a specific project.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewToken" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while creating the token." + }, + "404": { + "description": "The project could not be found." + }, + "409": { + "description": "The token already exists." + } + } } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{projectId}/tokens/default": { + "get": { + "tags": ["Token"], + "summary": "Get a projects default token", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } + }, + "/api/v2/tokens/{id}": { + "get": { + "tags": ["Token"], + "summary": "Get by id", + "operationId": "GetTokenById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the token.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "404": { + "description": "The token could not be found." + } + } + }, + "patch": { + "tags": ["Token"], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the token.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while updating the token." + }, + "404": { + "description": "The token could not be found." + } } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } + }, + "put": { + "tags": ["Token"], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the token.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while updating the token." + }, + "404": { + "description": "The token could not be found." + } } - } } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - }, - "post": { - "tags": [ - "Event" - ], - "summary": "Submit event by POST for a specific project", - "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" + }, + "/api/v2/tokens": { + "post": { + "tags": ["Token"], + "summary": "Create", + "description": "To create a new token, you must specify an organization_id. There are three valid scopes: client, user and admin.", + "requestBody": { + "description": "The token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewToken" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while creating the token." + }, + "409": { + "description": "The token already exists." + } + } } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" + }, + "/api/v2/tokens/{ids}": { + "delete": { + "tags": ["Token"], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of token identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more tokens were not found." + }, + "500": { + "description": "An error occurred while deleting one or more tokens." + } + } } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "string", - "example": "" - } + }, + "/api/v2/users/me": { + "get": { + "tags": ["User"], + "summary": "Get current user", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewCurrentUser" + } + } + } + }, + "404": { + "description": "The current user could not be found." + } + } }, - "text/plain": { - "schema": { - "type": "string", - "example": "" - } + "delete": { + "tags": ["User"], + "summary": "Delete current user", + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "404": { + "description": "The current user could not be found." + } + } } - }, - "required": true }, - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } - } - }, - "/api/v2/stacks/{stackId}/events": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get by stack", - "parameters": [ - { - "name": "stackId", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" + "/api/v2/users/{id}": { + "get": { + "tags": ["User"], + "summary": "Get by id", + "operationId": "GetUserById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + }, + "404": { + "description": "The user could not be found." + } + } + }, + "patch": { + "tags": ["User"], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + }, + "400": { + "description": "An error occurred while updating the user." + }, + "404": { + "description": "The user could not be found." + } + } + }, + "put": { + "tags": ["User"], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + }, + "400": { + "description": "An error occurred while updating the user." + }, + "404": { + "description": "The user could not be found." + } + } } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" + }, + "/api/v2/organizations/{organizationId}/users": { + "get": { + "tags": ["User"], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" + }, + "/api/v2/users/{ids}": { + "delete": { + "tags": ["User"], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of user identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more users were not found." + }, + "500": { + "description": "An error occurred while deleting one or more users." + } + } } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" + }, + "/api/v2/users/{id}/email-address/{email}": { + "post": { + "tags": ["User"], + "summary": "Update email address", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "email", + "in": "path", + "description": "The new email address.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateEmailAddressResult" + } + } + } + }, + "400": { + "description": "An error occurred while updating the users email address." + }, + "422": { + "description": "Validation error" + }, + "429": { + "description": "Update email address rate limit reached." + } + } } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" + }, + "/api/v2/users/verify-email-address/{token}": { + "get": { + "tags": ["User"], + "summary": "Verify email address", + "parameters": [ + { + "name": "token", + "in": "path", + "description": "The token identifier.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The user could not be found." + }, + "422": { + "description": "Verify Email Address Token has expired." + } + } } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 + }, + "/api/v2/users/{id}/resend-verification-email": { + "get": { + "tags": ["User"], + "summary": "Resend verification email", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "The user verification email has been sent." + }, + "404": { + "description": "The user could not be found." + } + } } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" + }, + "/api/v2/projects/{projectId}/webhooks": { + "get": { + "tags": ["WebHook"], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebHook" + } + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" + }, + "/api/v2/webhooks/{id}": { + "get": { + "tags": ["WebHook"], + "summary": "Get by id", + "operationId": "GetWebHookById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the web hook.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebHook" + } + } + } + }, + "404": { + "description": "The web hook could not be found." + } + } } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } + }, + "/api/v2/webhooks": { + "post": { + "tags": ["WebHook"], + "summary": "Create", + "requestBody": { + "description": "The web hook.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewWebHook" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebHook" + } + } + } + }, + "400": { + "description": "An error occurred while creating the web hook." + }, + "409": { + "description": "The web hook already exists." + } } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } + } + }, + "/api/v2/webhooks/{ids}": { + "delete": { + "tags": ["WebHook"], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of web hook identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more web hooks were not found." + }, + "500": { + "description": "An error occurred while deleting one or more web hooks." + } } - } } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The stack could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } } - } }, - "/api/v2/events/by-ref/{referenceId}": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get by reference id", - "parameters": [ - { - "name": "referenceId", - "in": "path", - "description": "An identifier used that references an event instance.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - } - }, - "/api/v2/projects/{projectId}/events/by-ref/{referenceId}": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get by reference id", - "parameters": [ - { - "name": "referenceId", - "in": "path", - "description": "An identifier used that references an event instance.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - } - }, - "/api/v2/events/sessions/{sessionId}": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get a list of all sessions or events by a session id", - "parameters": [ - { - "name": "sessionId", - "in": "path", - "description": "An identifier that represents a session of events.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - } - }, - "/api/v2/projects/{projectId}/events/sessions/{sessionId}": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get a list of by a session id", - "parameters": [ - { - "name": "sessionId", - "in": "path", - "description": "An identifier that represents a session of events.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - } - }, - "/api/v2/events/sessions": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get a list of all sessions", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - } - } - } - }, - "/api/v2/organizations/{organizationId}/events/sessions": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get a list of all sessions", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - } - }, - "/api/v2/projects/{projectId}/events/sessions": { - "get": { - "tags": [ - "Event" - ], - "summary": "Get a list of all sessions", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - } - }, - "/api/v2/events/by-ref/{referenceId}/user-description": { - "post": { - "tags": [ - "Event" - ], - "summary": "Set user description", - "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", - "parameters": [ - { - "name": "referenceId", - "in": "path", - "description": "An identifier used that references an event instance.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The user description.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserDescription" - } - } - } - }, - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "Description must be specified." - }, - "404": { - "description": "The event occurrence with the specified reference id could not be found." - } - } - } - }, - "/api/v2/projects/{projectId}/events/by-ref/{referenceId}/user-description": { - "post": { - "tags": [ - "Event" - ], - "summary": "Set user description", - "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", - "parameters": [ - { - "name": "referenceId", - "in": "path", - "description": "An identifier used that references an event instance.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The user description.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserDescription" - } - } - } - }, - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "Description must be specified." - }, - "404": { - "description": "The event occurrence with the specified reference id could not be found." - } - } - } - }, - "/api/v2/events/session/heartbeat": { - "get": { - "tags": [ - "Event" - ], - "summary": "Submit heartbeat", - "parameters": [ - { - "name": "id", - "in": "query", - "description": "The session id or user id.", - "schema": { - "type": "string" - } - }, - { - "name": "close", - "in": "query", - "description": "If true, the session will be closed.", - "schema": { - "type": "boolean", - "default": false - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } - } - }, - "/api/v2/events/submit": { - "get": { - "tags": [ - "Event" - ], - "summary": "Submit event by GET", - "description": "You can submit an event using an HTTP GET and query string parameters. Any unknown query string parameters will be added to the extended data of the event.\n \nFeature usage named build with a duration of 10:\n```/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", - "parameters": [ - { - "name": "type", - "in": "query", - "description": "The event type (ie. error, log message, feature usage).", - "schema": { - "type": "string" - } - }, - { - "name": "source", - "in": "query", - "description": "The event source (ie. machine name, log name, feature name).", - "schema": { - "type": "string" - } - }, - { - "name": "message", - "in": "query", - "description": "The event message.", - "schema": { - "type": "string" - } - }, - { - "name": "reference", - "in": "query", - "description": "An optional identifier to be used for referencing this event instance at a later time.", - "schema": { - "type": "string" - } - }, - { - "name": "date", - "in": "query", - "description": "The date that the event occurred on.", - "schema": { - "type": "string" - } - }, - { - "name": "count", - "in": "query", - "description": "The number of duplicated events.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "value", - "in": "query", - "description": "The value of the event if any.", - "schema": { - "type": "number", - "format": "double" - } - }, - { - "name": "geo", - "in": "query", - "description": "The geo coordinates where the event happened.", - "schema": { - "type": "string" - } - }, - { - "name": "tags", - "in": "query", - "description": "A list of tags used to categorize this event (comma separated).", - "schema": { - "type": "string" - } - }, - { - "name": "identity", - "in": "query", - "description": "The user's identity that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "identityname", - "in": "query", - "description": "The user's friendly name that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - }, - { - "name": "parameters", - "in": "query", - "description": "Query string parameters that control what properties are set on the event", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/StringStringValuesKeyValuePair" - } - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } - } - }, - "/api/v2/events/submit/{type}": { - "get": { - "tags": [ - "Event" - ], - "summary": "Submit event type by GET", - "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage event named build with a value of 10:\n```/events/submit/usage?access_token=YOUR_API_KEY&source=build&value=10```\n \nLog event with message, geo and extended data\n```/events/submit/log?access_token=YOUR_API_KEY&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", - "parameters": [ - { - "name": "type", - "in": "path", - "description": "The event type (ie. error, log message, feature usage).", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "source", - "in": "query", - "description": "The event source (ie. machine name, log name, feature name).", - "schema": { - "type": "string" - } - }, - { - "name": "message", - "in": "query", - "description": "The event message.", - "schema": { - "type": "string" - } - }, - { - "name": "reference", - "in": "query", - "description": "An optional identifier to be used for referencing this event instance at a later time.", - "schema": { - "type": "string" - } - }, - { - "name": "date", - "in": "query", - "description": "The date that the event occurred on.", - "schema": { - "type": "string" - } - }, - { - "name": "count", - "in": "query", - "description": "The number of duplicated events.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "value", - "in": "query", - "description": "The value of the event if any.", - "schema": { - "type": "number", - "format": "double" - } - }, - { - "name": "geo", - "in": "query", - "description": "The geo coordinates where the event happened.", - "schema": { - "type": "string" - } - }, - { - "name": "tags", - "in": "query", - "description": "A list of tags used to categorize this event (comma separated).", - "schema": { - "type": "string" - } - }, - { - "name": "identity", - "in": "query", - "description": "The user's identity that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "identityname", - "in": "query", - "description": "The user's friendly name that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - }, - { - "name": "parameters", - "in": "query", - "description": "Query string parameters that control what properties are set on the event", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/StringStringValuesKeyValuePair" - } - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } - } - }, - "/api/v2/projects/{projectId}/events/submit": { - "get": { - "tags": [ - "Event" - ], - "summary": "Submit event type by GET for a specific project", - "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "source", - "in": "query", - "description": "The event source (ie. machine name, log name, feature name).", - "schema": { - "type": "string" - } - }, - { - "name": "message", - "in": "query", - "description": "The event message.", - "schema": { - "type": "string" - } - }, - { - "name": "reference", - "in": "query", - "description": "An optional identifier to be used for referencing this event instance at a later time.", - "schema": { - "type": "string" - } - }, - { - "name": "date", - "in": "query", - "description": "The date that the event occurred on.", - "schema": { - "type": "string" - } - }, - { - "name": "count", - "in": "query", - "description": "The number of duplicated events.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "value", - "in": "query", - "description": "The value of the event if any.", - "schema": { - "type": "number", - "format": "double" - } - }, - { - "name": "geo", - "in": "query", - "description": "The geo coordinates where the event happened.", - "schema": { - "type": "string" - } - }, - { - "name": "tags", - "in": "query", - "description": "A list of tags used to categorize this event (comma separated).", - "schema": { - "type": "string" - } - }, - { - "name": "identity", - "in": "query", - "description": "The user's identity that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "identityname", - "in": "query", - "description": "The user's friendly name that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - }, - { - "name": "parameters", - "in": "query", - "description": "Query String parameters that control what properties are set on the event", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/StringStringValuesKeyValuePair" - } - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } - } - }, - "/api/v2/projects/{projectId}/events/submit/{type}": { - "get": { - "tags": [ - "Event" - ], - "summary": "Submit event type by GET for a specific project", - "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "type", - "in": "path", - "description": "The event type (ie. error, log message, feature usage).", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "source", - "in": "query", - "description": "The event source (ie. machine name, log name, feature name).", - "schema": { - "type": "string" - } - }, - { - "name": "message", - "in": "query", - "description": "The event message.", - "schema": { - "type": "string" - } - }, - { - "name": "reference", - "in": "query", - "description": "An optional identifier to be used for referencing this event instance at a later time.", - "schema": { - "type": "string" - } - }, - { - "name": "date", - "in": "query", - "description": "The date that the event occurred on.", - "schema": { - "type": "string" - } - }, - { - "name": "count", - "in": "query", - "description": "The number of duplicated events.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "value", - "in": "query", - "description": "The value of the event if any.", - "schema": { - "type": "number", - "format": "double" - } - }, - { - "name": "geo", - "in": "query", - "description": "The geo coordinates where the event happened.", - "schema": { - "type": "string" - } - }, - { - "name": "tags", - "in": "query", - "description": "A list of tags used to categorize this event (comma separated).", - "schema": { - "type": "string" - } - }, - { - "name": "identity", - "in": "query", - "description": "The user's identity that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "identityname", - "in": "query", - "description": "The user's friendly name that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - }, - { - "name": "parameters", - "in": "query", - "description": "Query String parameters that control what properties are set on the event", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/StringStringValuesKeyValuePair" - } - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } - } - }, - "/api/v2/events/{ids}": { - "delete": { - "tags": [ - "Event" - ], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of event identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more event occurrences were not found." - }, - "500": { - "description": "An error occurred while deleting one or more event occurrences." - } - } - } - }, - "/api/v2/organizations": { - "get": { - "tags": [ - "Organization" - ], - "summary": "Get all", - "parameters": [ - { - "name": "mode", - "in": "query", - "description": "If no mode is set then a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - } - } - } - }, - "post": { - "tags": [ - "Organization" - ], - "summary": "Create", - "requestBody": { - "description": "The organization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewOrganization" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - }, - "400": { - "description": "An error occurred while creating the organization." - }, - "409": { - "description": "The organization already exists." - } - } - } - }, - "/api/v2/organizations/{id}": { - "get": { - "tags": [ - "Organization" - ], - "summary": "Get by id", - "operationId": "GetOrganizationById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - }, - "404": { - "description": "The organization could not be found." - } - } - }, - "patch": { - "tags": [ - "Organization" - ], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - }, - "400": { - "description": "An error occurred while updating the organization." - }, - "404": { - "description": "The organization could not be found." - } - } - }, - "put": { - "tags": [ - "Organization" - ], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - }, - "400": { - "description": "An error occurred while updating the organization." - }, - "404": { - "description": "The organization could not be found." - } - } - } - }, - "/api/v2/organizations/{ids}": { - "delete": { - "tags": [ - "Organization" - ], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of organization identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more organizations were not found." - }, - "500": { - "description": "An error occurred while deleting one or more organizations." - } - } - } - }, - "/api/v2/organizations/invoice/{id}": { - "get": { - "tags": [ - "Organization" - ], - "summary": "Get invoice", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the invoice.", - "required": true, - "schema": { - "minLength": 10, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Invoice" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Invoice" - } - } - } - }, - "404": { - "description": "The invoice was not found." - } - } - } - }, - "/api/v2/organizations/{id}/invoices": { - "get": { - "tags": [ - "Organization" - ], - "summary": "Get invoices", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "before", - "in": "query", - "description": "A cursor for use in pagination. before is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, starting with obj_bar, your subsequent call can include before=obj_bar in order to fetch the previous page of the list.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "A cursor for use in pagination. after is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include after=obj_foo in order to fetch the next page of the list.", - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 12 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/InvoiceGridModel" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/InvoiceGridModel" - } - } - } - } - }, - "404": { - "description": "The organization was not found." - } - } - } - }, - "/api/v2/organizations/{id}/plans": { - "get": { - "tags": [ - "Organization" - ], - "summary": "Get plans", - "description": "Gets available plans for a specific organization.", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BillingPlan" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BillingPlan" - } - } - } - } - }, - "404": { - "description": "The organization was not found." - } - } - } - }, - "/api/v2/organizations/{id}/change-plan": { - "post": { - "tags": [ - "Organization" - ], - "summary": "Change plan", - "description": "Upgrades or downgrades the organizations plan.", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "planId", - "in": "query", - "description": "The identifier of the plan.", - "schema": { - "type": "string" - } - }, - { - "name": "stripeToken", - "in": "query", - "description": "The token returned from the stripe service.", - "schema": { - "type": "string" - } - }, - { - "name": "last4", - "in": "query", - "description": "The last four numbers of the card.", - "schema": { - "type": "string" - } - }, - { - "name": "couponId", - "in": "query", - "description": "The coupon id.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ChangePlanResult" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ChangePlanResult" - } - } - } - }, - "404": { - "description": "The organization was not found." - } - } - } - }, - "/api/v2/organizations/{id}/users/{email}": { - "post": { - "tags": [ - "Organization" - ], - "summary": "Add user", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "email", - "in": "path", - "description": "The email address of the user you wish to add to your organization.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "404": { - "description": "The organization was not found." - }, - "426": { - "description": "Please upgrade your plan to add an additional user." - } - } - }, - "delete": { - "tags": [ - "Organization" - ], - "summary": "Remove user", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "email", - "in": "path", - "description": "The email address of the user you wish to remove from your organization.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "The error occurred while removing the user from your organization" - }, - "404": { - "description": "The organization was not found." - } - } - } - }, - "/api/v2/organizations/{id}/data/{key}": { - "post": { - "tags": [ - "Organization" - ], - "summary": "Add custom data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "path", - "description": "The key name of the data object.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "requestBody": { - "description": "Any string value.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The organization was not found." - } - } - }, - "delete": { - "tags": [ - "Organization" - ], - "summary": "Remove custom data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "path", - "description": "The key name of the data object.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The organization was not found." - } - } - } - }, - "/api/v2/organizations/check-name": { - "get": { - "tags": [ - "Organization" - ], - "summary": "Check for unique name", - "parameters": [ - { - "name": "name", - "in": "query", - "description": "The organization name to check.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "201": { - "description": "The organization name is available." - }, - "204": { - "description": "The organization name is not available." - } - } - } - }, - "/api/v2/projects": { - "get": { - "tags": [ - "Project" - ], - "summary": "Get all", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewProject" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - } - } - } - }, - "post": { - "tags": [ - "Project" - ], - "summary": "Create", - "requestBody": { - "description": "The project.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewProject" - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - }, - "400": { - "description": "An error occurred while creating the project." - }, - "409": { - "description": "The project already exists." - } - } - } - }, - "/api/v2/organizations/{organizationId}/projects": { - "get": { - "tags": [ - "Project" - ], - "summary": "Get all", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewProject" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - } - }, - "404": { - "description": "The organization could not be found." - } - } - } - }, - "/api/v2/projects/{id}": { - "get": { - "tags": [ - "Project" - ], - "summary": "Get by id", - "operationId": "GetProjectById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } - }, - "patch": { - "tags": [ - "Project" - ], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - }, - "400": { - "description": "An error occurred while updating the project." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "put": { - "tags": [ - "Project" - ], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - }, - "400": { - "description": "An error occurred while updating the project." - }, - "404": { - "description": "The project could not be found." - } - } - } - }, - "/api/v2/projects/{ids}": { - "delete": { - "tags": [ - "Project" - ], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of project identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more projects were not found." - }, - "500": { - "description": "An error occurred while deleting one or more projects." - } - } - } - }, - "/api/v2/projects/config": { - "get": { - "tags": [ - "Project" - ], - "summary": "Get configuration settings", - "parameters": [ - { - "name": "v", - "in": "query", - "description": "The client configuration version.", - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ClientConfiguration" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ClientConfiguration" - } - } - } - }, - "304": { - "description": "The client configuration version is the current version." - }, - "404": { - "description": "The project could not be found." - } - } - } - }, - "/api/v2/projects/{id}/config": { - "get": { - "tags": [ - "Project" - ], - "summary": "Get configuration settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "v", - "in": "query", - "description": "The client configuration version.", - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ClientConfiguration" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ClientConfiguration" - } - } - } - }, - "304": { - "description": "The client configuration version is the current version." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "post": { - "tags": [ - "Project" - ], - "summary": "Add configuration value", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "query", - "description": "The key name of the configuration object.", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "The configuration value.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid configuration value." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "delete": { - "tags": [ - "Project" - ], - "summary": "Remove configuration value", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "query", - "description": "The key name of the configuration object.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid key value." - }, - "404": { - "description": "The project could not be found." - } - } - } - }, - "/api/v2/projects/{id}/reset-data": { - "get": { - "tags": [ - "Project" - ], - "summary": "Reset project data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "404": { - "description": "The project could not be found." - } - } - } - }, - "/api/v2/users/{userId}/projects/{id}/notifications": { - "get": { - "tags": [ - "Project" - ], - "summary": "Get user notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "userId", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } - }, - "put": { - "tags": [ - "Project" - ], - "summary": "Set user notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "userId", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The notification settings.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project could not be found." - } - } - }, - "post": { - "tags": [ - "Project" - ], - "summary": "Set user notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "userId", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The notification settings.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project could not be found." - } - } - }, - "delete": { - "tags": [ - "Project" - ], - "summary": "Remove user notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "userId", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project could not be found." - } - } - } - }, - "/api/v2/projects/{id}/{integration}/notifications": { - "put": { - "tags": [ - "Project" - ], - "summary": "Set an integrations notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "integration", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "requestBody": { - "description": "The notification settings.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project or integration could not be found." - }, - "426": { - "description": "Please upgrade your plan to enable integrations." - } - } - }, - "post": { - "tags": [ - "Project" - ], - "summary": "Set an integrations notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "integration", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "requestBody": { - "description": "The notification settings.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project or integration could not be found." - }, - "426": { - "description": "Please upgrade your plan to enable integrations." - } - } - } - }, - "/api/v2/projects/{id}/promotedtabs": { - "put": { - "tags": [ - "Project" - ], - "summary": "Promote tab", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "name", - "in": "query", - "description": "The tab name.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid tab name." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "post": { - "tags": [ - "Project" - ], - "summary": "Promote tab", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "name", - "in": "query", - "description": "The tab name.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid tab name." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "delete": { - "tags": [ - "Project" - ], - "summary": "Demote tab", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "name", - "in": "query", - "description": "The tab name.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid tab name." - }, - "404": { - "description": "The project could not be found." - } - } - } - }, - "/api/v2/projects/check-name": { - "get": { - "tags": [ - "Project" - ], - "summary": "Check for unique name", - "parameters": [ - { - "name": "name", - "in": "query", - "description": "The project name to check.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "201": { - "description": "The project name is available." - }, - "204": { - "description": "The project name is not available." - } - } - } - }, - "/api/v2/organizations/{organizationId}/projects/check-name": { - "get": { - "tags": [ - "Project" - ], - "summary": "Check for unique name", - "parameters": [ - { - "name": "name", - "in": "query", - "description": "The project name to check.", - "schema": { - "type": "string" - } - }, - { - "name": "organizationId", - "in": "path", - "description": "If set the check name will be scoped to a specific organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "201": { - "description": "The project name is available." - }, - "204": { - "description": "The project name is not available." - } - } - } - }, - "/api/v2/projects/{id}/data": { - "post": { - "tags": [ - "Project" - ], - "summary": "Add custom data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "query", - "description": "The key name of the data object.", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Any string value.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid key or value." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "delete": { - "tags": [ - "Project" - ], - "summary": "Remove custom data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "query", - "description": "The key name of the data object.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid key or value." - }, - "404": { - "description": "The project could not be found." - } - } - } - }, - "/api/v2/stacks/{id}": { - "get": { - "tags": [ - "Stack" - ], - "summary": "Get by id", - "operationId": "GetStackById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the `time` filter. This is used for time zone support.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Stack" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Stack" - } - } - } - }, - "404": { - "description": "The stack could not be found." - } - } - } - }, - "/api/v2/stacks/{ids}/mark-fixed": { - "post": { - "tags": [ - "Stack" - ], - "summary": "Mark fixed", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - }, - { - "name": "version", - "in": "query", - "description": "A version number that the stack was fixed in.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "404": { - "description": "One or more stacks could not be found." - } - } - } - }, - "/api/v2/stacks/{ids}/mark-snoozed": { - "post": { - "tags": [ - "Stack" - ], - "summary": "Mark the selected stacks as snoozed", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - }, - { - "name": "snoozeUntilUtc", - "in": "query", - "description": "A time that the stack should be snoozed until.", - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "404": { - "description": "One or more stacks could not be found." - } - } - } - }, - "/api/v2/stacks/{id}/add-link": { - "post": { - "tags": [ - "Stack" - ], - "summary": "Add reference link", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The reference link.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid reference link." - }, - "404": { - "description": "The stack could not be found." - } - } - } - }, - "/api/v2/stacks/{id}/remove-link": { - "post": { - "tags": [ - "Stack" - ], - "summary": "Remove reference link", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The reference link.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "204": { - "description": "The reference link was removed." - }, - "400": { - "description": "Invalid reference link." - }, - "404": { - "description": "The stack could not be found." - } - } - } - }, - "/api/v2/stacks/{ids}/mark-critical": { - "post": { - "tags": [ - "Stack" - ], - "summary": "Mark future occurrences as critical", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "One or more stacks could not be found." - } - } - }, - "delete": { - "tags": [ - "Stack" - ], - "summary": "Mark future occurrences as not critical", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The stacks were marked as not critical." - }, - "404": { - "description": "One or more stacks could not be found." - } - } - } - }, - "/api/v2/stacks/{ids}/change-status": { - "post": { - "tags": [ - "Stack" - ], - "summary": "Change stack status", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - }, - { - "name": "status", - "in": "query", - "description": "The status that the stack should be changed to.\n\nopen\n\nfixed\n\nregressed\n\nsnoozed\n\nignored\n\ndiscarded", - "schema": { - "$ref": "#/components/schemas/StackStatus" + "components": { + "schemas": { + "BillingPlan": { + "required": ["description", "id", "name"], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "price": { + "type": "number", + "format": "double" + }, + "max_projects": { + "type": "integer", + "format": "int32" + }, + "max_users": { + "type": "integer", + "format": "int32" + }, + "retention_days": { + "type": "integer", + "format": "int32" + }, + "max_events_per_month": { + "type": "integer", + "format": "int32" + }, + "has_premium_features": { + "type": "boolean" + }, + "is_hidden": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "BillingStatus": { + "enum": [0, 1, 2, 3, 4], + "type": "integer", + "format": "int32", + "x-enumNames": [ + "Trialing", + "Active", + "PastDue", + "Canceled", + "Unpaid" + ] + }, + "ChangePasswordModel": { + "required": ["current_password", "password"], + "type": "object", + "properties": { + "current_password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + } + }, + "additionalProperties": false + }, + "ChangePlanResult": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "message": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "ClientConfiguration": { + "type": "object", + "properties": { + "version": { + "type": "integer", + "format": "int32" + }, + "settings": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "readOnly": true + } + }, + "additionalProperties": false + }, + "CountResult": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int64" + }, + "aggregations": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/IAggregate" + }, + "nullable": true + }, + "data": { + "type": "object", + "additionalProperties": { + "nullable": true + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "ExternalAuthInfo": { + "required": ["clientId", "code", "redirectUri"], + "type": "object", + "properties": { + "clientId": { + "minLength": 1, + "type": "string" + }, + "code": { + "minLength": 1, + "type": "string" + }, + "redirectUri": { + "minLength": 1, + "type": "string" + }, + "inviteToken": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "IAggregate": { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "nullable": true + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "Invite": { + "required": ["date_added", "email_address", "token"], + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "email_address": { + "type": "string" + }, + "date_added": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "Invoice": { + "required": [ + "date", + "id", + "organization_id", + "organization_name", + "paid", + "total" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "organization_name": { + "type": "string" + }, + "date": { + "type": "string", + "format": "date-time" + }, + "paid": { + "type": "boolean" + }, + "total": { + "type": "number", + "format": "double" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InvoiceLineItem" + } + } + }, + "additionalProperties": false + }, + "InvoiceGridModel": { + "required": ["date", "id", "paid"], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "date": { + "type": "string", + "format": "date-time" + }, + "paid": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "InvoiceLineItem": { + "required": ["amount", "description"], + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "date": { + "type": "string", + "nullable": true + }, + "amount": { + "type": "number", + "format": "double" + } + }, + "additionalProperties": false + }, + "Login": { + "required": ["email", "password"], + "type": "object", + "properties": { + "email": { + "minLength": 1, + "type": "string", + "description": "The email address or domain username" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + }, + "invite_token": { + "maxLength": 40, + "minLength": 40, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "NewOrganization": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false }, - "x-enumNames": [ - "Open", - "Fixed", - "Regressed", - "Snoozed", - "Ignored", - "Discarded" - ] - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "One or more stacks could not be found." - } - } - } - }, - "/api/v2/stacks/{id}/promote": { - "post": { - "tags": [ - "Stack" - ], - "summary": "Promote to external service", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The stack could not be found." - }, - "426": { - "description": "Promote to External is a premium feature used to promote an error stack to an external system." - }, - "501": { - "description": "No promoted web hooks are configured for this project." - } - } - } - }, - "/api/v2/stacks/{ids}": { - "delete": { - "tags": [ - "Stack" - ], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more stacks were not found." - }, - "500": { - "description": "An error occurred while deleting one or more stacks." - } - } - } - }, - "/api/v2/stacks": { - "get": { - "tags": [ - "Stack" - ], - "summary": "Get all", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Stack" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Stack" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - } - } - } - }, - "/api/v2/organizations/{organizationId}/stacks": { - "get": { - "tags": [ - "Stack" - ], - "summary": "Get by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Stack" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Stack" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The organization could not be found." - }, - "426": { - "description": "Unable to view stack occurrences for the suspended organization." - } - } - } - }, - "/api/v2/projects/{projectId}/stacks": { - "get": { - "tags": [ - "Stack" - ], - "summary": "Get by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Stack" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Stack" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The organization could not be found." - }, - "426": { - "description": "Unable to view stack occurrences for the suspended organization." - } - } - } - }, - "/api/v2/organizations/{organizationId}/tokens": { - "get": { - "tags": [ - "Token" - ], - "summary": "Get by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewToken" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - } - }, - "404": { - "description": "The organization could not be found." - } - } - }, - "post": { - "tags": [ - "Token" - ], - "summary": "Create for organization", - "description": "This is a helper action that makes it easier to create a token for a specific organization.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The token.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewToken" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while creating the token." - }, - "409": { - "description": "The token already exists." - } - } - } - }, - "/api/v2/projects/{projectId}/tokens": { - "get": { - "tags": [ - "Token" - ], - "summary": "Get by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewToken" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } - }, - "post": { - "tags": [ - "Token" - ], - "summary": "Create for project", - "description": "This is a helper action that makes it easier to create a token for a specific project.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The token.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewToken" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while creating the token." - }, - "404": { - "description": "The project could not be found." - }, - "409": { - "description": "The token already exists." - } - } - } - }, - "/api/v2/projects/{projectId}/tokens/default": { - "get": { - "tags": [ - "Token" - ], - "summary": "Get a projects default token", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } - } - }, - "/api/v2/tokens/{id}": { - "get": { - "tags": [ - "Token" - ], - "summary": "Get by id", - "operationId": "GetTokenById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the token.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "404": { - "description": "The token could not be found." - } - } - }, - "patch": { - "tags": [ - "Token" - ], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the token.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while updating the token." - }, - "404": { - "description": "The token could not be found." - } - } - }, - "put": { - "tags": [ - "Token" - ], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the token.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while updating the token." - }, - "404": { - "description": "The token could not be found." - } - } - } - }, - "/api/v2/tokens": { - "post": { - "tags": [ - "Token" - ], - "summary": "Create", - "description": "To create a new token, you must specify an organization_id. There are three valid scopes: client, user and admin.", - "requestBody": { - "description": "The token.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewToken" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while creating the token." - }, - "409": { - "description": "The token already exists." - } - } - } - }, - "/api/v2/tokens/{ids}": { - "delete": { - "tags": [ - "Token" - ], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of token identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more tokens were not found." - }, - "500": { - "description": "An error occurred while deleting one or more tokens." - } - } - } - }, - "/api/v2/users/me": { - "get": { - "tags": [ - "User" - ], - "summary": "Get current user", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewCurrentUser" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewCurrentUser" - } - } - } - }, - "404": { - "description": "The current user could not be found." - } - } - }, - "delete": { - "tags": [ - "User" - ], - "summary": "Delete current user", - "responses": { - "202": { - "description": "Accepted" - }, - "404": { - "description": "The current user could not be found." - } - } - } - }, - "/api/v2/users/{id}": { - "get": { - "tags": [ - "User" - ], - "summary": "Get by id", - "operationId": "GetUserById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewUser" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewUser" - } - } - } - }, - "404": { - "description": "The user could not be found." - } - } - }, - "patch": { - "tags": [ - "User" - ], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewUser" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewUser" - } - } - } - }, - "400": { - "description": "An error occurred while updating the user." - }, - "404": { - "description": "The user could not be found." - } - } - }, - "put": { - "tags": [ - "User" - ], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewUser" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ViewUser" - } - } - } - }, - "400": { - "description": "An error occurred while updating the user." - }, - "404": { - "description": "The user could not be found." - } - } - } - }, - "/api/v2/organizations/{organizationId}/users": { - "get": { - "tags": [ - "User" - ], - "summary": "Get by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewUser" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewUser" - } - } - } - } - }, - "404": { - "description": "The organization could not be found." - } - } - } - }, - "/api/v2/users/{ids}": { - "delete": { - "tags": [ - "User" - ], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of user identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more users were not found." - }, - "500": { - "description": "An error occurred while deleting one or more users." - } - } - } - }, - "/api/v2/users/{id}/email-address/{email}": { - "post": { - "tags": [ - "User" - ], - "summary": "Update email address", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "email", - "in": "path", - "description": "The new email address.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateEmailAddressResult" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/UpdateEmailAddressResult" - } - } - } - }, - "400": { - "description": "An error occurred while updating the users email address." - }, - "422": { - "description": "Validation error" - }, - "429": { - "description": "Update email address rate limit reached." - } - } - } - }, - "/api/v2/users/verify-email-address/{token}": { - "get": { - "tags": [ - "User" - ], - "summary": "Verify email address", - "parameters": [ - { - "name": "token", - "in": "path", - "description": "The token identifier.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The user could not be found." - }, - "422": { - "description": "Verify Email Address Token has expired." - } - } - } - }, - "/api/v2/users/{id}/resend-verification-email": { - "get": { - "tags": [ - "User" - ], - "summary": "Resend verification email", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "The user verification email has been sent." - }, - "404": { - "description": "The user could not be found." - } - } - } - }, - "/api/v2/projects/{projectId}/webhooks": { - "get": { - "tags": [ - "WebHook" - ], - "summary": "Get by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/WebHook" - } - } - }, - "application/problem+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/WebHook" - } - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } - } - }, - "/api/v2/webhooks/{id}": { - "get": { - "tags": [ - "WebHook" - ], - "summary": "Get by id", - "operationId": "GetWebHookById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the web hook.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebHook" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/WebHook" - } - } - } - }, - "404": { - "description": "The web hook could not be found." - } - } - } - }, - "/api/v2/webhooks": { - "post": { - "tags": [ - "WebHook" - ], - "summary": "Create", - "requestBody": { - "description": "The web hook.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewWebHook" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebHook" - } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/WebHook" - } - } - } - }, - "400": { - "description": "An error occurred while creating the web hook." - }, - "409": { - "description": "The web hook already exists." - } - } - } - }, - "/api/v2/webhooks/{ids}": { - "delete": { - "tags": [ - "WebHook" - ], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of web hook identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more web hooks were not found." - }, - "500": { - "description": "An error occurred while deleting one or more web hooks." - } - } - } - } - }, - "components": { - "schemas": { - "BillingPlan": { - "required": [ - "description", - "id", - "name" - ], - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "price": { - "type": "number", - "format": "double" - }, - "max_projects": { - "type": "integer", - "format": "int32" - }, - "max_users": { - "type": "integer", - "format": "int32" - }, - "retention_days": { - "type": "integer", - "format": "int32" - }, - "max_events_per_month": { - "type": "integer", - "format": "int32" - }, - "has_premium_features": { - "type": "boolean" - }, - "is_hidden": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "BillingStatus": { - "enum": [ - 0, - 1, - 2, - 3, - 4 - ], - "type": "integer", - "description": "\n\n0 = Trialing\n\n1 = Active\n\n2 = PastDue\n\n3 = Canceled\n\n4 = Unpaid", - "format": "int32", - "x-enumNames": [ - "Trialing", - "Active", - "PastDue", - "Canceled", - "Unpaid" - ] - }, - "ChangePasswordModel": { - "required": [ - "current_password", - "password" - ], - "type": "object", - "properties": { - "current_password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - }, - "password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - } - }, - "additionalProperties": false - }, - "ChangePlanResult": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - }, - "message": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "ClientConfiguration": { - "type": "object", - "properties": { - "version": { - "type": "integer", - "format": "int32" - }, - "settings": { - "type": "object", - "additionalProperties": { - "type": "string" + "NewProject": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "delete_bot_data_enabled": { + "type": "boolean" + } + }, + "additionalProperties": false }, - "readOnly": true - } - }, - "additionalProperties": false - }, - "CountResult": { - "type": "object", - "properties": { - "total": { - "type": "integer", - "format": "int64" - }, - "aggregations": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/IAggregate" + "NewToken": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "default_project_id": { + "type": "string", + "nullable": true + }, + "scopes": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "expires_utc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "notes": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false }, - "nullable": true - }, - "data": { - "type": "object", - "additionalProperties": { - "nullable": true + "NewWebHook": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "url": { + "type": "string" + }, + "event_types": { + "type": "array", + "items": { + "type": "string" + } + }, + "version": { + "type": "string", + "description": "The schema version that should be used.", + "nullable": true + } + }, + "additionalProperties": false }, - "nullable": true - } - }, - "additionalProperties": false - }, - "ExternalAuthInfo": { - "required": [ - "clientId", - "code", - "redirectUri" - ], - "type": "object", - "properties": { - "clientId": { - "minLength": 1, - "type": "string" - }, - "code": { - "minLength": 1, - "type": "string" - }, - "redirectUri": { - "minLength": 1, - "type": "string" - }, - "inviteToken": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "IAggregate": { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": { - "nullable": true + "NotificationSettings": { + "type": "object", + "properties": { + "send_daily_summary": { + "type": "boolean" + }, + "report_new_errors": { + "type": "boolean" + }, + "report_critical_errors": { + "type": "boolean" + }, + "report_event_regressions": { + "type": "boolean" + }, + "report_new_events": { + "type": "boolean" + }, + "report_critical_events": { + "type": "boolean" + } + }, + "additionalProperties": false }, - "nullable": true - } - }, - "additionalProperties": false - }, - "Invite": { - "required": [ - "date_added", - "email_address", - "token" - ], - "type": "object", - "properties": { - "token": { - "type": "string" - }, - "email_address": { - "type": "string" - }, - "date_added": { - "type": "string", - "format": "date-time" - } - }, - "additionalProperties": false - }, - "Invoice": { - "required": [ - "date", - "id", - "organization_id", - "organization_name", - "paid", - "total" - ], - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "organization_name": { - "type": "string" - }, - "date": { - "type": "string", - "format": "date-time" - }, - "paid": { - "type": "boolean" - }, - "total": { - "type": "number", - "format": "double" - }, - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/InvoiceLineItem" - } - } - }, - "additionalProperties": false - }, - "InvoiceGridModel": { - "required": [ - "date", - "id", - "paid" - ], - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "date": { - "type": "string", - "format": "date-time" - }, - "paid": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "InvoiceLineItem": { - "required": [ - "amount", - "description" - ], - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "date": { - "type": "string", - "nullable": true - }, - "amount": { - "type": "number", - "format": "double" - } - }, - "additionalProperties": false - }, - "Login": { - "required": [ - "email", - "password" - ], - "type": "object", - "properties": { - "email": { - "minLength": 1, - "type": "string", - "description": "The email address or domain username" - }, - "password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - }, - "invite_token": { - "maxLength": 40, - "minLength": 40, - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "NewOrganization": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - }, - "additionalProperties": false - }, - "NewProject": { - "type": "object", - "properties": { - "organization_id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "delete_bot_data_enabled": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "NewToken": { - "type": "object", - "properties": { - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "default_project_id": { - "type": "string", - "nullable": true - }, - "scopes": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "expires_utc": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "notes": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "NewWebHook": { - "type": "object", - "properties": { - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "url": { - "type": "string" - }, - "event_types": { - "type": "array", - "items": { - "type": "string" - } - }, - "version": { - "type": "string", - "description": "The schema version that should be used.", - "nullable": true - } - }, - "additionalProperties": false - }, - "NotificationSettings": { - "type": "object", - "properties": { - "send_daily_summary": { - "type": "boolean" - }, - "report_new_errors": { - "type": "boolean" - }, - "report_critical_errors": { - "type": "boolean" - }, - "report_event_regressions": { - "type": "boolean" - }, - "report_new_events": { - "type": "boolean" - }, - "report_critical_events": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "OAuthAccount": { - "required": [ - "provider", - "provider_user_id", - "username" - ], - "type": "object", - "properties": { - "provider": { - "type": "string" - }, - "provider_user_id": { - "type": "string" - }, - "username": { - "type": "string" - }, - "extra_data": { - "type": "object", - "additionalProperties": { - "type": "string" + "OAuthAccount": { + "required": ["provider", "provider_user_id", "username"], + "type": "object", + "properties": { + "provider": { + "type": "string" + }, + "provider_user_id": { + "type": "string" + }, + "username": { + "type": "string" + }, + "extra_data": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "readOnly": true + } + }, + "additionalProperties": false }, - "readOnly": true - } - }, - "additionalProperties": false - }, - "PersistentEvent": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "stack_id": { - "type": "string" - }, - "is_first_occurrence": { - "type": "boolean" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "idx": { - "type": "object", - "additionalProperties": { } - }, - "type": { - "type": "string", - "nullable": true - }, - "source": { - "type": "string", - "nullable": true - }, - "date": { - "type": "string", - "format": "date-time" - }, - "tags": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" + "PersistentEvent": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "stack_id": { + "type": "string" + }, + "is_first_occurrence": { + "type": "boolean" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "idx": { + "type": "object", + "additionalProperties": {} + }, + "type": { + "type": "string", + "nullable": true + }, + "source": { + "type": "string", + "nullable": true + }, + "date": { + "type": "string", + "format": "date-time" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, + "message": { + "type": "string", + "nullable": true + }, + "geo": { + "type": "string", + "nullable": true + }, + "value": { + "type": "number", + "format": "double", + "nullable": true + }, + "count": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "data": { + "type": "object", + "additionalProperties": {}, + "nullable": true + }, + "reference_id": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false }, - "nullable": true - }, - "message": { - "type": "string", - "nullable": true - }, - "geo": { - "type": "string", - "nullable": true - }, - "value": { - "type": "number", - "format": "double", - "nullable": true - }, - "count": { - "type": "integer", - "format": "int32", - "nullable": true - }, - "data": { - "type": "object", - "additionalProperties": { }, - "nullable": true - }, - "reference_id": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "ResetPasswordModel": { - "required": [ - "password", - "password_reset_token" - ], - "type": "object", - "properties": { - "password_reset_token": { - "maxLength": 40, - "minLength": 40, - "type": "string" - }, - "password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - } - }, - "additionalProperties": false - }, - "Signup": { - "required": [ - "email", - "name", - "password" - ], - "type": "object", - "properties": { - "name": { - "minLength": 1, - "type": "string" - }, - "email": { - "minLength": 1, - "type": "string", - "description": "The email address or domain username" - }, - "password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - }, - "invite_token": { - "maxLength": 40, - "minLength": 40, - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "Stack": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "status": { - "$ref": "#/components/schemas/StackStatus" - }, - "snooze_until_utc": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "signature_hash": { - "type": "string" - }, - "signature_info": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "fixed_in_version": { - "type": "string", - "nullable": true - }, - "date_fixed": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "title": { - "type": "string" - }, - "total_occurrences": { - "type": "integer", - "format": "int32" - }, - "first_occurrence": { - "type": "string", - "format": "date-time" - }, - "last_occurrence": { - "type": "string", - "format": "date-time" - }, - "description": { - "type": "string", - "nullable": true - }, - "occurrences_are_critical": { - "type": "boolean" - }, - "references": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "duplicate_signature": { - "type": "string" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "updated_utc": { - "type": "string", - "format": "date-time" - }, - "is_deleted": { - "type": "boolean" - }, - "allow_notifications": { - "type": "boolean", - "readOnly": true - } - }, - "additionalProperties": false - }, - "StackStatus": { - "enum": [ - "open", - "fixed", - "regressed", - "snoozed", - "ignored", - "discarded" - ], - "type": "string", - "description": "\n\nopen\n\nfixed\n\nregressed\n\nsnoozed\n\nignored\n\ndiscarded", - "x-enumNames": [ - "Open", - "Fixed", - "Regressed", - "Snoozed", - "Ignored", - "Discarded" - ] - }, - "StringStringValuesKeyValuePair": { - "type": "object", - "properties": { - "key": { - "type": "string", - "nullable": true - }, - "value": { - "type": "array", - "items": { - "type": "string" + "ResetPasswordModel": { + "required": ["password", "password_reset_token"], + "type": "object", + "properties": { + "password_reset_token": { + "maxLength": 40, + "minLength": 40, + "type": "string" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + } + }, + "additionalProperties": false + }, + "Signup": { + "required": ["email", "name", "password"], + "type": "object", + "properties": { + "name": { + "minLength": 1, + "type": "string" + }, + "email": { + "minLength": 1, + "type": "string", + "description": "The email address or domain username" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + }, + "invite_token": { + "maxLength": 40, + "minLength": 40, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "Stack": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/StackStatus" + }, + "snooze_until_utc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "signature_hash": { + "type": "string" + }, + "signature_info": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "fixed_in_version": { + "type": "string", + "nullable": true + }, + "date_fixed": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "title": { + "type": "string" + }, + "total_occurrences": { + "type": "integer", + "format": "int32" + }, + "first_occurrence": { + "type": "string", + "format": "date-time" + }, + "last_occurrence": { + "type": "string", + "format": "date-time" + }, + "description": { + "type": "string", + "nullable": true + }, + "occurrences_are_critical": { + "type": "boolean" + }, + "references": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "duplicate_signature": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "updated_utc": { + "type": "string", + "format": "date-time" + }, + "is_deleted": { + "type": "boolean" + }, + "allow_notifications": { + "type": "boolean", + "readOnly": true + } + }, + "additionalProperties": false + }, + "StackStatus": { + "enum": [ + "open", + "fixed", + "regressed", + "snoozed", + "ignored", + "discarded" + ], + "type": "string", + "x-enumNames": [ + "Open", + "Fixed", + "Regressed", + "Snoozed", + "Ignored", + "Discarded" + ] + }, + "StringStringValuesKeyValuePair": { + "type": "object", + "properties": { + "key": { + "type": "string", + "nullable": true + }, + "value": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "StringValueFromBody": { + "type": "object", + "properties": { + "value": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "TokenResult": { + "required": ["token"], + "type": "object", + "properties": { + "token": { + "minLength": 1, + "type": "string" + } + }, + "additionalProperties": false + }, + "UpdateEmailAddressResult": { + "required": ["is_verified"], + "type": "object", + "properties": { + "is_verified": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "UsageHourInfo": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "total": { + "type": "integer", + "format": "int32" + }, + "blocked": { + "type": "integer", + "format": "int32" + }, + "discarded": { + "type": "integer", + "format": "int32" + }, + "too_big": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "UsageInfo": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "limit": { + "type": "integer", + "format": "int32" + }, + "total": { + "type": "integer", + "format": "int32" + }, + "blocked": { + "type": "integer", + "format": "int32" + }, + "discarded": { + "type": "integer", + "format": "int32" + }, + "too_big": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "User": { + "required": ["email_address", "full_name"], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_ids": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + }, + "readOnly": true + }, + "password": { + "type": "string", + "nullable": true + }, + "salt": { + "type": "string", + "nullable": true + }, + "password_reset_token": { + "type": "string", + "nullable": true + }, + "password_reset_token_expiration": { + "type": "string", + "format": "date-time" + }, + "o_auth_accounts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OAuthAccount" + }, + "readOnly": true + }, + "full_name": { + "minLength": 1, + "type": "string" + }, + "email_address": { + "minLength": 1, + "type": "string", + "format": "email" + }, + "email_notifications_enabled": { + "type": "boolean" + }, + "is_email_address_verified": { + "type": "boolean" + }, + "verify_email_address_token": { + "type": "string", + "nullable": true + }, + "verify_email_address_token_expiration": { + "type": "string", + "format": "date-time" + }, + "is_active": { + "type": "boolean" + }, + "roles": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "updated_utc": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "UserDescription": { + "type": "object", + "properties": { + "email_address": { + "type": "string", + "nullable": true + }, + "description": { + "type": "string", + "nullable": true + }, + "data": { + "type": "object", + "additionalProperties": {}, + "nullable": true + } + }, + "additionalProperties": false + }, + "ViewCurrentUser": { + "type": "object", + "properties": { + "hash": { + "type": "string", + "nullable": true + }, + "has_local_account": { + "type": "boolean" + }, + "o_auth_accounts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OAuthAccount" + } + }, + "id": { + "type": "string" + }, + "organization_ids": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "full_name": { + "type": "string" + }, + "email_address": { + "type": "string" + }, + "email_notifications_enabled": { + "type": "boolean" + }, + "is_email_address_verified": { + "type": "boolean" + }, + "is_active": { + "type": "boolean" + }, + "is_invite": { + "type": "boolean" + }, + "roles": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "ViewOrganization": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "plan_id": { + "type": "string" + }, + "plan_name": { + "type": "string" + }, + "plan_description": { + "type": "string" + }, + "card_last4": { + "type": "string", + "nullable": true + }, + "subscribe_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "billing_change_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "billing_changed_by_user_id": { + "type": "string", + "nullable": true + }, + "billing_status": { + "$ref": "#/components/schemas/BillingStatus" + }, + "billing_price": { + "type": "number", + "format": "double" + }, + "max_events_per_month": { + "type": "integer", + "format": "int32" + }, + "bonus_events_per_month": { + "type": "integer", + "format": "int32" + }, + "bonus_expiration": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "retention_days": { + "type": "integer", + "format": "int32" + }, + "is_suspended": { + "type": "boolean" + }, + "suspension_code": { + "type": "string", + "nullable": true + }, + "suspension_notes": { + "type": "string", + "nullable": true + }, + "suspension_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "has_premium_features": { + "type": "boolean" + }, + "max_users": { + "type": "integer", + "format": "int32" + }, + "max_projects": { + "type": "integer", + "format": "int32" + }, + "project_count": { + "type": "integer", + "format": "int64" + }, + "stack_count": { + "type": "integer", + "format": "int64" + }, + "event_count": { + "type": "integer", + "format": "int64" + }, + "invites": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Invite" + } + }, + "usage_hours": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageHourInfo" + } + }, + "usage": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageInfo" + } + }, + "data": { + "type": "object", + "additionalProperties": {}, + "nullable": true + }, + "is_throttled": { + "type": "boolean" + }, + "is_over_monthly_limit": { + "type": "boolean" + }, + "is_over_request_limit": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "ViewProject": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "organization_id": { + "type": "string" + }, + "organization_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "delete_bot_data_enabled": { + "type": "boolean" + }, + "data": { + "type": "object", + "additionalProperties": {}, + "nullable": true + }, + "promoted_tabs": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "is_configured": { + "type": "boolean", + "nullable": true + }, + "stack_count": { + "type": "integer", + "format": "int64" + }, + "event_count": { + "type": "integer", + "format": "int64" + }, + "has_premium_features": { + "type": "boolean" + }, + "has_slack_integration": { + "type": "boolean" + }, + "usage_hours": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageHourInfo" + } + }, + "usage": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageInfo" + } + } + }, + "additionalProperties": false + }, + "ViewToken": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "user_id": { + "type": "string", + "nullable": true + }, + "default_project_id": { + "type": "string", + "nullable": true + }, + "scopes": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "expires_utc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "notes": { + "type": "string", + "nullable": true + }, + "is_disabled": { + "type": "boolean" + }, + "is_suspended": { + "type": "boolean" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "updated_utc": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "ViewUser": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_ids": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "full_name": { + "type": "string" + }, + "email_address": { + "type": "string" + }, + "email_notifications_enabled": { + "type": "boolean" + }, + "is_email_address_verified": { + "type": "boolean" + }, + "is_active": { + "type": "boolean" + }, + "is_invite": { + "type": "boolean" + }, + "roles": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "WebHook": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "url": { + "type": "string" + }, + "event_types": { + "type": "array", + "items": { + "type": "string" + } + }, + "is_enabled": { + "type": "boolean" + }, + "version": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "WorkInProgressResult": { + "type": "object", + "properties": { + "workers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false } - } }, - "additionalProperties": false - }, - "StringValueFromBody": { - "type": "object", - "properties": { - "value": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "TokenResult": { - "required": [ - "token" - ], - "type": "object", - "properties": { - "token": { - "minLength": 1, - "type": "string" - } - }, - "additionalProperties": false - }, - "UpdateEmailAddressResult": { - "required": [ - "is_verified" - ], - "type": "object", - "properties": { - "is_verified": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "UsageHourInfo": { - "type": "object", - "properties": { - "date": { - "type": "string", - "format": "date-time" - }, - "total": { - "type": "integer", - "format": "int32" - }, - "blocked": { - "type": "integer", - "format": "int32" - }, - "discarded": { - "type": "integer", - "format": "int32" - }, - "too_big": { - "type": "integer", - "format": "int32" - } - }, - "additionalProperties": false - }, - "UsageInfo": { - "type": "object", - "properties": { - "date": { - "type": "string", - "format": "date-time" - }, - "limit": { - "type": "integer", - "format": "int32" - }, - "total": { - "type": "integer", - "format": "int32" - }, - "blocked": { - "type": "integer", - "format": "int32" - }, - "discarded": { - "type": "integer", - "format": "int32" - }, - "too_big": { - "type": "integer", - "format": "int32" - } - }, - "additionalProperties": false - }, - "User": { - "required": [ - "email_address", - "full_name" - ], - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_ids": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" + "securitySchemes": { + "Basic": { + "type": "http", + "description": "Basic HTTP Authentication", + "scheme": "basic" }, - "readOnly": true - }, - "password": { - "type": "string", - "nullable": true - }, - "salt": { - "type": "string", - "nullable": true - }, - "password_reset_token": { - "type": "string", - "nullable": true - }, - "password_reset_token_expiration": { - "type": "string", - "format": "date-time" - }, - "o_auth_accounts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/OAuthAccount" + "Bearer": { + "type": "http", + "description": "Authorization token. Example: \"Bearer {apikey}\"", + "scheme": "bearer" }, - "readOnly": true - }, - "full_name": { - "minLength": 1, - "type": "string" - }, - "email_address": { - "minLength": 1, - "type": "string", - "format": "email" - }, - "email_notifications_enabled": { - "type": "boolean" - }, - "is_email_address_verified": { - "type": "boolean" - }, - "verify_email_address_token": { - "type": "string", - "nullable": true - }, - "verify_email_address_token_expiration": { - "type": "string", - "format": "date-time" - }, - "is_active": { - "type": "boolean" - }, - "roles": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" + "Token": { + "type": "apiKey", + "description": "Authorization token. Example: \"Bearer {apikey}\"", + "name": "access_token", + "in": "query" } - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "updated_utc": { - "type": "string", - "format": "date-time" - } - }, - "additionalProperties": false - }, - "UserDescription": { - "type": "object", - "properties": { - "email_address": { - "type": "string", - "nullable": true - }, - "description": { - "type": "string", - "nullable": true - }, - "data": { - "type": "object", - "additionalProperties": { }, - "nullable": true - } + } + }, + "security": [ + { + "Basic": [], + "Bearer": [], + "Token": [] + } + ], + "tags": [ + { + "name": "Auth" }, - "additionalProperties": false - }, - "ViewCurrentUser": { - "type": "object", - "properties": { - "hash": { - "type": "string", - "nullable": true - }, - "has_local_account": { - "type": "boolean" - }, - "o_auth_accounts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/OAuthAccount" - } - }, - "id": { - "type": "string" - }, - "organization_ids": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "full_name": { - "type": "string" - }, - "email_address": { - "type": "string" - }, - "email_notifications_enabled": { - "type": "boolean" - }, - "is_email_address_verified": { - "type": "boolean" - }, - "is_active": { - "type": "boolean" - }, - "is_invite": { - "type": "boolean" - }, - "roles": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - } + { + "name": "Event" }, - "additionalProperties": false - }, - "ViewOrganization": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "name": { - "type": "string" - }, - "plan_id": { - "type": "string" - }, - "plan_name": { - "type": "string" - }, - "plan_description": { - "type": "string" - }, - "card_last4": { - "type": "string", - "nullable": true - }, - "subscribe_date": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "billing_change_date": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "billing_changed_by_user_id": { - "type": "string", - "nullable": true - }, - "billing_status": { - "$ref": "#/components/schemas/BillingStatus" - }, - "billing_price": { - "type": "number", - "format": "double" - }, - "max_events_per_month": { - "type": "integer", - "format": "int32" - }, - "bonus_events_per_month": { - "type": "integer", - "format": "int32" - }, - "bonus_expiration": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "retention_days": { - "type": "integer", - "format": "int32" - }, - "is_suspended": { - "type": "boolean" - }, - "suspension_code": { - "type": "string", - "nullable": true - }, - "suspension_notes": { - "type": "string", - "nullable": true - }, - "suspension_date": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "has_premium_features": { - "type": "boolean" - }, - "max_users": { - "type": "integer", - "format": "int32" - }, - "max_projects": { - "type": "integer", - "format": "int32" - }, - "project_count": { - "type": "integer", - "format": "int64" - }, - "stack_count": { - "type": "integer", - "format": "int64" - }, - "event_count": { - "type": "integer", - "format": "int64" - }, - "invites": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Invite" - } - }, - "usage_hours": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UsageHourInfo" - } - }, - "usage": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UsageInfo" - } - }, - "data": { - "type": "object", - "additionalProperties": { }, - "nullable": true - }, - "is_throttled": { - "type": "boolean" - }, - "is_over_monthly_limit": { - "type": "boolean" - }, - "is_over_request_limit": { - "type": "boolean" - } + { + "name": "Organization" }, - "additionalProperties": false - }, - "ViewProject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "organization_id": { - "type": "string" - }, - "organization_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "delete_bot_data_enabled": { - "type": "boolean" - }, - "data": { - "type": "object", - "additionalProperties": { }, - "nullable": true - }, - "promoted_tabs": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "is_configured": { - "type": "boolean", - "nullable": true - }, - "stack_count": { - "type": "integer", - "format": "int64" - }, - "event_count": { - "type": "integer", - "format": "int64" - }, - "has_premium_features": { - "type": "boolean" - }, - "has_slack_integration": { - "type": "boolean" - }, - "usage_hours": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UsageHourInfo" - } - }, - "usage": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UsageInfo" - } - } + { + "name": "Project" }, - "additionalProperties": false - }, - "ViewToken": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "user_id": { - "type": "string", - "nullable": true - }, - "default_project_id": { - "type": "string", - "nullable": true - }, - "scopes": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "expires_utc": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "notes": { - "type": "string", - "nullable": true - }, - "is_disabled": { - "type": "boolean" - }, - "is_suspended": { - "type": "boolean" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "updated_utc": { - "type": "string", - "format": "date-time" - } + { + "name": "Stack" }, - "additionalProperties": false - }, - "ViewUser": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_ids": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "full_name": { - "type": "string" - }, - "email_address": { - "type": "string" - }, - "email_notifications_enabled": { - "type": "boolean" - }, - "is_email_address_verified": { - "type": "boolean" - }, - "is_active": { - "type": "boolean" - }, - "is_invite": { - "type": "boolean" - }, - "roles": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - } + { + "name": "Token" }, - "additionalProperties": false - }, - "WebHook": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "url": { - "type": "string" - }, - "event_types": { - "type": "array", - "items": { - "type": "string" - } - }, - "is_enabled": { - "type": "boolean" - }, - "version": { - "type": "string" - }, - "created_utc": { - "type": "string", - "format": "date-time" - } + { + "name": "User" }, - "additionalProperties": false - } - }, - "securitySchemes": { - "Basic": { - "type": "http", - "description": "Basic HTTP Authentication", - "scheme": "basic" - }, - "Bearer": { - "type": "http", - "description": "Authorization token. Example: \"Bearer {apikey}\"", - "scheme": "bearer" - }, - "Token": { - "type": "apiKey", - "description": "Authorization token. Example: \"Bearer {apikey}\"", - "name": "access_token", - "in": "query" - } - } - }, - "security": [ - { - "Basic": [ ], - "Bearer": [ ], - "Token": [ ] - } - ] -} \ No newline at end of file + { + "name": "WebHook" + } + ] +} diff --git a/tests/Exceptionless.Tests/Controllers/OpenApiControllerTests.cs b/tests/Exceptionless.Tests/Controllers/OpenApiControllerTests.cs index 497f193977..7ec16b84e3 100644 --- a/tests/Exceptionless.Tests/Controllers/OpenApiControllerTests.cs +++ b/tests/Exceptionless.Tests/Controllers/OpenApiControllerTests.cs @@ -11,17 +11,22 @@ public OpenApiControllerTests(ITestOutputHelper output, AppWebHostFactory factor } [Fact] - public async Task GetSwaggerJson_ReturnsExpectedBaseline() + public async Task GetSwaggerJson_Default_ReturnsExpectedBaseline() { + // Arrange + string baselinePath = Path.Combine("..", "..", "..", "Controllers", "Data", "swagger.json"); + + // Act var response = await SendRequestAsync(r => r .BaseUri(_server.BaseAddress) .AppendPaths("docs", "v2", "swagger.json") .StatusCodeShouldBeOk() ); - string baselinePath = Path.Combine("..", "..", "..", "Controllers", "Data", "swagger.json"); - string expectedJson = await File.ReadAllTextAsync(baselinePath); string actualJson = await response.Content.ReadAsStringAsync(); + + // Assert + string expectedJson = await File.ReadAllTextAsync(baselinePath); Assert.Equal(expectedJson, actualJson); } } From 7ea585c5cf3ffa2fcc511c33f8f926153c31acf9 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Thu, 4 Dec 2025 22:52:03 -0600 Subject: [PATCH 12/14] Upgrades dependencies Updates project dependencies to the latest versions, including Aspire, FluentValidation, MaxMind.GeoIP2, Serilog, and OpenTelemetry, to leverage the newest features, improvements, and bug fixes. --- src/Exceptionless.AppHost/Exceptionless.AppHost.csproj | 7 ++++--- src/Exceptionless.Core/Exceptionless.Core.csproj | 2 +- .../Exceptionless.Insulation.csproj | 6 +++--- src/Exceptionless.Job/Exceptionless.Job.csproj | 8 ++++---- src/Exceptionless.Web/Exceptionless.Web.csproj | 8 ++++---- tests/Exceptionless.Tests/Exceptionless.Tests.csproj | 4 ++-- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj index e3f7cfe7e8..78913d2034 100644 --- a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj +++ b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj @@ -1,4 +1,4 @@ - + Exe net10.0 @@ -7,8 +7,9 @@ a9c2ddcc-e51d-4cd1-9782-96e1d74eec87 - - + + + diff --git a/src/Exceptionless.Core/Exceptionless.Core.csproj b/src/Exceptionless.Core/Exceptionless.Core.csproj index e42893e952..9b43ec14f4 100644 --- a/src/Exceptionless.Core/Exceptionless.Core.csproj +++ b/src/Exceptionless.Core/Exceptionless.Core.csproj @@ -22,7 +22,7 @@ - + diff --git a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj index 2d5acf37e0..487dee149a 100644 --- a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj +++ b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj @@ -1,7 +1,7 @@ - + @@ -15,9 +15,9 @@ - + - + diff --git a/src/Exceptionless.Job/Exceptionless.Job.csproj b/src/Exceptionless.Job/Exceptionless.Job.csproj index 244ad58392..55191de242 100644 --- a/src/Exceptionless.Job/Exceptionless.Job.csproj +++ b/src/Exceptionless.Job/Exceptionless.Job.csproj @@ -6,7 +6,7 @@ - + @@ -14,11 +14,11 @@ - - + + - + diff --git a/src/Exceptionless.Web/Exceptionless.Web.csproj b/src/Exceptionless.Web/Exceptionless.Web.csproj index 354b9eb571..c53397f1d6 100644 --- a/src/Exceptionless.Web/Exceptionless.Web.csproj +++ b/src/Exceptionless.Web/Exceptionless.Web.csproj @@ -20,7 +20,7 @@ - + @@ -28,11 +28,11 @@ - - + + - + diff --git a/tests/Exceptionless.Tests/Exceptionless.Tests.csproj b/tests/Exceptionless.Tests/Exceptionless.Tests.csproj index 0305fe17d8..f94d82b2e0 100644 --- a/tests/Exceptionless.Tests/Exceptionless.Tests.csproj +++ b/tests/Exceptionless.Tests/Exceptionless.Tests.csproj @@ -9,12 +9,12 @@ - + - + runtime; build; native; contentfiles; analyzers; buildtransitive From cf98afc7fe12cfe573d6fa5f2840666d76114d15 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Thu, 4 Dec 2025 23:29:17 -0600 Subject: [PATCH 13/14] Updates UI and testing configuration Refactors UI components by adjusting sizes and widths for better display. Changes the test runner entry point to use array syntax. --- Dockerfile | 2 +- .../events/components/events-stack-chart.svelte | 2 +- .../shared/components/ui/chart/chart-tooltip.svelte | 2 +- .../lib/features/stacks/components/stack-card.svelte | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5b174756d2..0b0ee130ba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,7 +24,7 @@ RUN dotnet build -c Release FROM build AS testrunner WORKDIR /app/tests/Exceptionless.Tests -ENTRYPOINT dotnet test --results-directory /app/artifacts --logger:trx +ENTRYPOINT ["dotnet", "test", "--results-directory", "/app/artifacts", "--logger:trx"] # job-publish diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/events-stack-chart.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/events-stack-chart.svelte index c2c0a7f9c8..2ae5be93ef 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/events-stack-chart.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/events-stack-chart.svelte @@ -63,7 +63,7 @@ }} > {#snippet tooltip()} - formatDateLabel(value)} /> + formatDateLabel(value)} /> {/snippet} diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/ui/chart/chart-tooltip.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/ui/chart/chart-tooltip.svelte index d0e1aaeae0..d2868fef5f 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/ui/chart/chart-tooltip.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/ui/chart/chart-tooltip.svelte @@ -86,7 +86,7 @@
- - + +
- - + +
@@ -233,8 +233,8 @@ {#each { length: 4 } as name, index (`${name}-${index}`)}
- - + +
{/each}
From d9042b53f7d969a3c273aaa57ed215a1c9dd6946 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Thu, 4 Dec 2025 23:43:01 -0600 Subject: [PATCH 14/14] Fixed tests --- .../Data/event-serialization-response.json | 2 +- .../Controllers/Data/swagger.json | 14449 ++++++++-------- 2 files changed, 7364 insertions(+), 7087 deletions(-) diff --git a/tests/Exceptionless.Tests/Controllers/Data/event-serialization-response.json b/tests/Exceptionless.Tests/Controllers/Data/event-serialization-response.json index 5c81f267a7..b1a558af13 100644 --- a/tests/Exceptionless.Tests/Controllers/Data/event-serialization-response.json +++ b/tests/Exceptionless.Tests/Controllers/Data/event-serialization-response.json @@ -27,7 +27,7 @@ }, "@submission_client": { "user_agent": "fluentrest", - "version": "10.1.0.0" + "version": "11.0.0.0" }, "@environment": { "processor_count": 8, diff --git a/tests/Exceptionless.Tests/Controllers/Data/swagger.json b/tests/Exceptionless.Tests/Controllers/Data/swagger.json index 6bc77c2765..4945c31d31 100644 --- a/tests/Exceptionless.Tests/Controllers/Data/swagger.json +++ b/tests/Exceptionless.Tests/Controllers/Data/swagger.json @@ -1,7225 +1,7502 @@ { - "openapi": "3.0.4", - "info": { - "title": "Exceptionless API", - "termsOfService": "https://exceptionless.com/terms/", - "contact": { - "name": "Exceptionless", - "url": "https://github.com/exceptionless/Exceptionless", - "email": "" - }, - "license": { - "name": "Apache License 2.0", - "url": "https://github.com/exceptionless/Exceptionless/blob/main/LICENSE.txt" - }, - "version": "v2" + "openapi": "3.0.4", + "info": { + "title": "Exceptionless API", + "termsOfService": "https://exceptionless.com/terms/", + "contact": { + "name": "Exceptionless", + "url": "https://github.com/exceptionless/Exceptionless", + "email": "" }, - "paths": { - "/api/v2/auth/login": { - "post": { - "tags": ["Auth"], - "summary": "Login", - "description": "Log in with your email address and password to generate a token scoped with your users roles.\n \n```{ \"email\": \"noreply@exceptionless.io\", \"password\": \"exceptionless\" }```\n \nThis token can then be used to access the api. You can use this token in the header (bearer authentication)\nor append it onto the query string: ?access_token=MY_TOKEN\n \nPlease note that you can also use this token on the documentation site by placing it in the\nheaders api_key input box.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Login" - } - } - } - }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "401": { - "description": "Login failed" - }, - "422": { - "description": "Validation error" - } - } + "license": { + "name": "Apache License 2.0", + "url": "https://github.com/exceptionless/Exceptionless/blob/main/LICENSE.txt" + }, + "version": "v2" + }, + "paths": { + "/api/v2/auth/login": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Login", + "description": "Log in with your email address and password to generate a token scoped with your users roles.\n \n```{ \"email\": \"noreply@exceptionless.io\", \"password\": \"exceptionless\" }```\n \nThis token can then be used to access the api. You can use this token in the header (bearer authentication)\nor append it onto the query string: ?access_token=MY_TOKEN\n \nPlease note that you can also use this token on the documentation site by placing it in the\nheaders api_key input box.", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Login" + } } + } }, - "/api/v2/auth/logout": { - "get": { - "tags": ["Auth"], - "summary": "Logout the current user and remove the current access token", - "responses": { - "200": { - "description": "User successfully logged-out" - }, - "401": { - "description": "User not logged in" - }, - "403": { - "description": "Current action is not supported with user access token" - } + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" } + } } - }, - "/api/v2/auth/signup": { - "post": { - "tags": ["Auth"], - "summary": "Sign up", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Signup" - } - } - } - }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "401": { - "description": "Sign-up failed" - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } - } + }, + "401": { + "description": "Login failed" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/logout": { + "get": { + "tags": [ + "Auth" + ], + "summary": "Logout the current user and remove the current access token", + "responses": { + "200": { + "description": "User successfully logged-out" + }, + "401": { + "description": "User not logged in" + }, + "403": { + "description": "Current action is not supported with user access token" + } + } + } + }, + "/api/v2/auth/signup": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign up", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Signup" + } } + } }, - "/api/v2/auth/github": { - "post": { - "tags": ["Auth"], - "summary": "Sign in with GitHub", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalAuthInfo" - } - } - } - }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" } + } } - }, - "/api/v2/auth/google": { - "post": { - "tags": ["Auth"], - "summary": "Sign in with Google", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalAuthInfo" - } - } - } - }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } - } + }, + "401": { + "description": "Sign-up failed" + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/github": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign in with GitHub", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } } + } }, - "/api/v2/auth/facebook": { - "post": { - "tags": ["Auth"], - "summary": "Sign in with Facebook", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalAuthInfo" - } - } - } - }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" } + } } - }, - "/api/v2/auth/live": { - "post": { - "tags": ["Auth"], - "summary": "Sign in with Microsoft", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExternalAuthInfo" - } - } - } - }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "403": { - "description": "Account Creation is currently disabled" - }, - "422": { - "description": "Validation error" - } - } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/google": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign in with Google", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } } + } }, - "/api/v2/auth/unlink/{providerName}": { - "post": { - "tags": ["Auth"], - "summary": "Removes an external login provider from the account", - "parameters": [ - { - "name": "providerName", - "in": "path", - "description": "The provider name.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "requestBody": { - "description": "The provider user id.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "400": { - "description": "Invalid provider name." - } + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" } + } } - }, - "/api/v2/auth/change-password": { - "post": { - "tags": ["Auth"], - "summary": "Change password", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ChangePasswordModel" - } - } - } - }, - "responses": { - "200": { - "description": "User Authentication Token", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResult" - } - } - } - }, - "422": { - "description": "Validation error" - } - } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/facebook": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign in with Facebook", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } } + } }, - "/api/v2/auth/forgot-password/{email}": { - "get": { - "tags": ["Auth"], - "summary": "Forgot password", - "parameters": [ - { - "name": "email", - "in": "path", - "description": "The email address.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Forgot password email was sent." - }, - "400": { - "description": "Invalid email address." - } + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" } + } } - }, - "/api/v2/auth/reset-password": { - "post": { - "tags": ["Auth"], - "summary": "Reset password", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ResetPasswordModel" - } - } - } - }, - "responses": { - "200": { - "description": "Password reset email was sent." - }, - "422": { - "description": "Invalid reset password model." - } - } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/live": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Sign in with Microsoft", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExternalAuthInfo" + } } + } }, - "/api/v2/auth/cancel-reset-password/{token}": { - "post": { - "tags": ["Auth"], - "summary": "Cancel reset password", - "parameters": [ - { - "name": "token", - "in": "path", - "description": "The password reset token.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Password reset email was cancelled." - }, - "400": { - "description": "Invalid password reset token." - } + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" } + } } - }, - "/api/v2/events/count": { - "get": { - "tags": ["Event"], - "summary": "Count", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "aggregations", - "in": "query", - "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CountResult" - } - } - } - }, - "400": { - "description": "Invalid filter." - } - } + }, + "403": { + "description": "Account Creation is currently disabled" + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/unlink/{providerName}": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Removes an external login provider from the account", + "parameters": [ + { + "name": "providerName", + "in": "path", + "description": "The provider name.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" } - }, - "/api/v2/organizations/{organizationId}/events/count": { - "get": { - "tags": ["Event"], - "summary": "Count by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "aggregations", - "in": "query", - "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CountResult" - } - } - } - }, - "400": { - "description": "Invalid filter." - } - } + } + ], + "requestBody": { + "description": "The provider user id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } } + } }, - "/api/v2/projects/{projectId}/events/count": { - "get": { - "tags": ["Event"], - "summary": "Count by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "aggregations", - "in": "query", - "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If mode is set to stack_new, then additional filters will be added.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CountResult" - } - } - } - }, - "400": { - "description": "Invalid filter." - } + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" } + } } - }, - "/api/v2/events/{id}": { - "get": { - "tags": ["Event"], - "summary": "Get by id", - "operationId": "GetPersistentEventById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the event.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - }, - "404": { - "description": "The event occurrence could not be found." - }, - "426": { - "description": "Unable to view event occurrence due to plan limits." - } - } + }, + "400": { + "description": "Invalid provider name." + } + } + } + }, + "/api/v2/auth/change-password": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Change password", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChangePasswordModel" + } } + } }, - "/api/v2/events": { - "get": { - "tags": ["Event"], - "summary": "Get all", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - }, - "post": { - "tags": ["Event"], - "summary": "Submit event by POST", - "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", - "parameters": [ - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "string", - "example": "" - } - }, - "text/plain": { - "schema": { - "type": "string", - "example": "" - } - } - }, - "required": true - }, - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } + "responses": { + "200": { + "description": "User Authentication Token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResult" } + } } - }, - "/api/v2/organizations/{organizationId}/events": { - "get": { - "tags": ["Event"], - "summary": "Get by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The organization could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } + }, + "422": { + "description": "Validation error" + } + } + } + }, + "/api/v2/auth/forgot-password/{email}": { + "get": { + "tags": [ + "Auth" + ], + "summary": "Forgot password", + "parameters": [ + { + "name": "email", + "in": "path", + "description": "The email address.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" } - }, - "/api/v2/projects/{projectId}/events": { - "get": { - "tags": ["Event"], - "summary": "Get by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } - }, - "post": { - "tags": ["Event"], - "summary": "Submit event by POST for a specific project", - "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "string", - "example": "" - } - }, - "text/plain": { - "schema": { - "type": "string", - "example": "" - } - } - }, - "required": true - }, - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } + } + ], + "responses": { + "200": { + "description": "Forgot password email was sent." + }, + "400": { + "description": "Invalid email address." + } + } + } + }, + "/api/v2/auth/reset-password": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Reset password", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPasswordModel" + } } + } }, - "/api/v2/stacks/{stackId}/events": { - "get": { - "tags": ["Event"], - "summary": "Get by stack", - "parameters": [ - { - "name": "stackId", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The stack could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } + "responses": { + "200": { + "description": "Password reset email was sent." + }, + "422": { + "description": "Invalid reset password model." + } + } + } + }, + "/api/v2/auth/cancel-reset-password/{token}": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Cancel reset password", + "parameters": [ + { + "name": "token", + "in": "path", + "description": "The password reset token.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" } - }, - "/api/v2/events/by-ref/{referenceId}": { - "get": { - "tags": ["Event"], - "summary": "Get by reference id", - "parameters": [ - { - "name": "referenceId", - "in": "path", - "description": "An identifier used that references an event instance.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } + } + ], + "responses": { + "200": { + "description": "Password reset email was cancelled." + }, + "400": { + "description": "Invalid password reset token." + } + } + } + }, + "/api/v2/events/count": { + "get": { + "tags": [ + "Event" + ], + "summary": "Count", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{projectId}/events/by-ref/{referenceId}": { - "get": { - "tags": ["Event"], - "summary": "Get by reference id", - "parameters": [ - { - "name": "referenceId", - "in": "path", - "description": "An identifier used that references an event instance.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } + }, + { + "name": "aggregations", + "in": "query", + "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", + "schema": { + "type": "string" } - }, - "/api/v2/events/sessions/{sessionId}": { - "get": { - "tags": ["Event"], - "summary": "Get a list of all sessions or events by a session id", - "parameters": [ - { - "name": "sessionId", - "in": "path", - "description": "An identifier that represents a session of events.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{projectId}/events/sessions/{sessionId}": { - "get": { - "tags": ["Event"], - "summary": "Get a list of by a session id", - "parameters": [ - { - "name": "sessionId", - "in": "path", - "description": "An identifier that represents a session of events.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" } - }, - "/api/v2/events/sessions": { - "get": { - "tags": ["Event"], - "summary": "Get a list of all sessions", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - } - } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/{organizationId}/events/sessions": { - "get": { - "tags": ["Event"], - "summary": "Get a list of all sessions", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CountResult" } + } } - }, - "/api/v2/projects/{projectId}/events/sessions": { - "get": { - "tags": ["Event"], - "summary": "Get a list of all sessions", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "before", - "in": "query", - "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PersistentEvent" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The project could not be found." - }, - "426": { - "description": "Unable to view event occurrences for the suspended organization." - } - } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/organizations/{organizationId}/events/count": { + "get": { + "tags": [ + "Event" + ], + "summary": "Count by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" } - }, - "/api/v2/events/by-ref/{referenceId}/user-description": { - "post": { - "tags": ["Event"], - "summary": "Set user description", - "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", - "parameters": [ - { - "name": "referenceId", - "in": "path", - "description": "An identifier used that references an event instance.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The user description.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserDescription" - } - } - } - }, - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "Description must be specified." - }, - "404": { - "description": "The event occurrence with the specified reference id could not be found." - } - } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{projectId}/events/by-ref/{referenceId}/user-description": { - "post": { - "tags": ["Event"], - "summary": "Set user description", - "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", - "parameters": [ - { - "name": "referenceId", - "in": "path", - "description": "An identifier used that references an event instance.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{8,100}$", - "type": "string" - } - }, - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The user description.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserDescription" - } - } - } - }, - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "Description must be specified." - }, - "404": { - "description": "The event occurrence with the specified reference id could not be found." - } - } + }, + { + "name": "aggregations", + "in": "query", + "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", + "schema": { + "type": "string" } - }, - "/api/v2/events/session/heartbeat": { - "get": { - "tags": ["Event"], - "summary": "Submit heartbeat", - "parameters": [ - { - "name": "id", - "in": "query", - "description": "The session id or user id.", - "schema": { - "type": "string" - } - }, - { - "name": "close", - "in": "query", - "description": "If true, the session will be closed.", - "schema": { - "type": "boolean", - "default": false - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" } - }, - "/api/v2/events/submit": { - "get": { - "tags": ["Event"], - "summary": "Submit event by GET", - "description": "You can submit an event using an HTTP GET and query string parameters. Any unknown query string parameters will be added to the extended data of the event.\n \nFeature usage named build with a duration of 10:\n```/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", - "parameters": [ - { - "name": "type", - "in": "query", - "description": "The event type (ie. error, log message, feature usage).", - "schema": { - "type": "string" - } - }, - { - "name": "source", - "in": "query", - "description": "The event source (ie. machine name, log name, feature name).", - "schema": { - "type": "string" - } - }, - { - "name": "message", - "in": "query", - "description": "The event message.", - "schema": { - "type": "string" - } - }, - { - "name": "reference", - "in": "query", - "description": "An optional identifier to be used for referencing this event instance at a later time.", - "schema": { - "type": "string" - } - }, - { - "name": "date", - "in": "query", - "description": "The date that the event occurred on.", - "schema": { - "type": "string" - } - }, - { - "name": "count", - "in": "query", - "description": "The number of duplicated events.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "value", - "in": "query", - "description": "The value of the event if any.", - "schema": { - "type": "number", - "format": "double" - } - }, - { - "name": "geo", - "in": "query", - "description": "The geo coordinates where the event happened.", - "schema": { - "type": "string" - } - }, - { - "name": "tags", - "in": "query", - "description": "A list of tags used to categorize this event (comma separated).", - "schema": { - "type": "string" - } - }, - { - "name": "identity", - "in": "query", - "description": "The user's identity that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "identityname", - "in": "query", - "description": "The user's friendly name that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - }, - { - "name": "parameters", - "in": "query", - "description": "Query string parameters that control what properties are set on the event", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/StringStringValuesKeyValuePair" - } - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" } - }, - "/api/v2/events/submit/{type}": { - "get": { - "tags": ["Event"], - "summary": "Submit event type by GET", - "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage event named build with a value of 10:\n```/events/submit/usage?access_token=YOUR_API_KEY&source=build&value=10```\n \nLog event with message, geo and extended data\n```/events/submit/log?access_token=YOUR_API_KEY&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", - "parameters": [ - { - "name": "type", - "in": "path", - "description": "The event type (ie. error, log message, feature usage).", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "source", - "in": "query", - "description": "The event source (ie. machine name, log name, feature name).", - "schema": { - "type": "string" - } - }, - { - "name": "message", - "in": "query", - "description": "The event message.", - "schema": { - "type": "string" - } - }, - { - "name": "reference", - "in": "query", - "description": "An optional identifier to be used for referencing this event instance at a later time.", - "schema": { - "type": "string" - } - }, - { - "name": "date", - "in": "query", - "description": "The date that the event occurred on.", - "schema": { - "type": "string" - } - }, - { - "name": "count", - "in": "query", - "description": "The number of duplicated events.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "value", - "in": "query", - "description": "The value of the event if any.", - "schema": { - "type": "number", - "format": "double" - } - }, - { - "name": "geo", - "in": "query", - "description": "The geo coordinates where the event happened.", - "schema": { - "type": "string" - } - }, - { - "name": "tags", - "in": "query", - "description": "A list of tags used to categorize this event (comma separated).", - "schema": { - "type": "string" - } - }, - { - "name": "identity", - "in": "query", - "description": "The user's identity that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "identityname", - "in": "query", - "description": "The user's friendly name that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - }, - { - "name": "parameters", - "in": "query", - "description": "Query string parameters that control what properties are set on the event", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/StringStringValuesKeyValuePair" - } - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{projectId}/events/submit": { - "get": { - "tags": ["Event"], - "summary": "Submit event type by GET for a specific project", - "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "source", - "in": "query", - "description": "The event source (ie. machine name, log name, feature name).", - "schema": { - "type": "string" - } - }, - { - "name": "message", - "in": "query", - "description": "The event message.", - "schema": { - "type": "string" - } - }, - { - "name": "reference", - "in": "query", - "description": "An optional identifier to be used for referencing this event instance at a later time.", - "schema": { - "type": "string" - } - }, - { - "name": "date", - "in": "query", - "description": "The date that the event occurred on.", - "schema": { - "type": "string" - } - }, - { - "name": "count", - "in": "query", - "description": "The number of duplicated events.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "value", - "in": "query", - "description": "The value of the event if any.", - "schema": { - "type": "number", - "format": "double" - } - }, - { - "name": "geo", - "in": "query", - "description": "The geo coordinates where the event happened.", - "schema": { - "type": "string" - } - }, - { - "name": "tags", - "in": "query", - "description": "A list of tags used to categorize this event (comma separated).", - "schema": { - "type": "string" - } - }, - { - "name": "identity", - "in": "query", - "description": "The user's identity that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "identityname", - "in": "query", - "description": "The user's friendly name that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - }, - { - "name": "parameters", - "in": "query", - "description": "Query String parameters that control what properties are set on the event", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/StringStringValuesKeyValuePair" - } - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CountResult" } + } } - }, - "/api/v2/projects/{projectId}/events/submit/{type}": { - "get": { - "tags": ["Event"], - "summary": "Submit event type by GET for a specific project", - "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "type", - "in": "path", - "description": "The event type (ie. error, log message, feature usage).", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "source", - "in": "query", - "description": "The event source (ie. machine name, log name, feature name).", - "schema": { - "type": "string" - } - }, - { - "name": "message", - "in": "query", - "description": "The event message.", - "schema": { - "type": "string" - } - }, - { - "name": "reference", - "in": "query", - "description": "An optional identifier to be used for referencing this event instance at a later time.", - "schema": { - "type": "string" - } - }, - { - "name": "date", - "in": "query", - "description": "The date that the event occurred on.", - "schema": { - "type": "string" - } - }, - { - "name": "count", - "in": "query", - "description": "The number of duplicated events.", - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "value", - "in": "query", - "description": "The value of the event if any.", - "schema": { - "type": "number", - "format": "double" - } - }, - { - "name": "geo", - "in": "query", - "description": "The geo coordinates where the event happened.", - "schema": { - "type": "string" - } - }, - { - "name": "tags", - "in": "query", - "description": "A list of tags used to categorize this event (comma separated).", - "schema": { - "type": "string" - } - }, - { - "name": "identity", - "in": "query", - "description": "The user's identity that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "identityname", - "in": "query", - "description": "The user's friendly name that the event happened to.", - "schema": { - "type": "string" - } - }, - { - "name": "userAgent", - "in": "header", - "description": "The user agent that submitted the event.", - "schema": { - "type": "string" - } - }, - { - "name": "parameters", - "in": "query", - "description": "Query String parameters that control what properties are set on the event", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/StringStringValuesKeyValuePair" - } - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "No project id specified and no default project was found." - }, - "404": { - "description": "No project was found." - } - } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/projects/{projectId}/events/count": { + "get": { + "tags": [ + "Event" + ], + "summary": "Count by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" } - }, - "/api/v2/events/{ids}": { - "delete": { - "tags": ["Event"], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of event identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WorkInProgressResult" - } - } - } - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more event occurrences were not found." - }, - "500": { - "description": "An error occurred while deleting one or more event occurrences." - } - } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations": { - "get": { - "tags": ["Organization"], - "summary": "Get all", - "parameters": [ - { - "name": "mode", - "in": "query", - "description": "If no mode is set then a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - } - } - } - }, - "post": { - "tags": ["Organization"], - "summary": "Create", - "requestBody": { - "description": "The organization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewOrganization" - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - }, - "400": { - "description": "An error occurred while creating the organization." - }, - "409": { - "description": "The organization already exists." - } - } + }, + { + "name": "aggregations", + "in": "query", + "description": "A list of values you want returned. Example: avg:value cardinality:value sum:users max:value min:value", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/{id}": { - "get": { - "tags": ["Organization"], - "summary": "Get by id", - "operationId": "GetOrganizationById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - }, - "404": { - "description": "The organization could not be found." - } - } - }, - "patch": { - "tags": ["Organization"], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - }, - "400": { - "description": "An error occurred while updating the organization." - }, - "404": { - "description": "The organization could not be found." - } - } - }, - "put": { - "tags": ["Organization"], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewOrganization" - } - } - } - }, - "400": { - "description": "An error occurred while updating the organization." - }, - "404": { - "description": "The organization could not be found." - } - } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/{ids}": { - "delete": { - "tags": ["Organization"], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of organization identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WorkInProgressResult" - } - } - } - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more organizations were not found." - }, - "500": { - "description": "An error occurred while deleting one or more organizations." - } - } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/invoice/{id}": { - "get": { - "tags": ["Organization"], - "summary": "Get invoice", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the invoice.", - "required": true, - "schema": { - "minLength": 10, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Invoice" - } - } - } - }, - "404": { - "description": "The invoice was not found." - } - } + }, + { + "name": "mode", + "in": "query", + "description": "If mode is set to stack_new, then additional filters will be added.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/{id}/invoices": { - "get": { - "tags": ["Organization"], - "summary": "Get invoices", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "before", - "in": "query", - "description": "A cursor for use in pagination. before is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, starting with obj_bar, your subsequent call can include before=obj_bar in order to fetch the previous page of the list.", - "schema": { - "type": "string" - } - }, - { - "name": "after", - "in": "query", - "description": "A cursor for use in pagination. after is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include after=obj_foo in order to fetch the next page of the list.", - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 12 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/InvoiceGridModel" - } - } - } - } - }, - "404": { - "description": "The organization was not found." - } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CountResult" } + } } - }, - "/api/v2/organizations/{id}/plans": { - "get": { - "tags": ["Organization"], - "summary": "Get plans", - "description": "Gets available plans for a specific organization.", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BillingPlan" - } - } - } - } - }, - "404": { - "description": "The organization was not found." - } - } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/events/{id}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by id", + "operationId": "GetPersistentEventById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the event.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" } - }, - "/api/v2/organizations/{id}/change-plan": { - "post": { - "tags": ["Organization"], - "summary": "Change plan", - "description": "Upgrades or downgrades the organizations plan.", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "planId", - "in": "query", - "description": "The identifier of the plan.", - "schema": { - "type": "string" - } - }, - { - "name": "stripeToken", - "in": "query", - "description": "The token returned from the stripe service.", - "schema": { - "type": "string" - } - }, - { - "name": "last4", - "in": "query", - "description": "The last four numbers of the card.", - "schema": { - "type": "string" - } - }, - { - "name": "couponId", - "in": "query", - "description": "The coupon id.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ChangePlanResult" - } - } - } - }, - "404": { - "description": "The organization was not found." - } - } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/{id}/users/{email}": { - "post": { - "tags": ["Organization"], - "summary": "Add user", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "email", - "in": "path", - "description": "The email address of the user you wish to add to your organization.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "404": { - "description": "The organization was not found." - }, - "426": { - "description": "Please upgrade your plan to add an additional user." - } - } - }, - "delete": { - "tags": ["Organization"], - "summary": "Remove user", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "email", - "in": "path", - "description": "The email address of the user you wish to remove from your organization.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "The error occurred while removing the user from your organization" - }, - "404": { - "description": "The organization was not found." - } - } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/{id}/data/{key}": { - "post": { - "tags": ["Organization"], - "summary": "Add custom data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "path", - "description": "The key name of the data object.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "requestBody": { - "description": "Any string value.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The organization was not found." - } - } - }, - "delete": { - "tags": ["Organization"], - "summary": "Remove custom data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "path", - "description": "The key name of the data object.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The organization was not found." - } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersistentEvent" } + } } - }, - "/api/v2/organizations/check-name": { - "get": { - "tags": ["Organization"], - "summary": "Check for unique name", - "parameters": [ - { - "name": "name", - "in": "query", - "description": "The organization name to check.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "201": { - "description": "The organization name is available." - }, - "204": { - "description": "The organization name is not available." - } - } + }, + "404": { + "description": "The event occurrence could not be found." + }, + "426": { + "description": "Unable to view event occurrence due to plan limits." + } + } + } + }, + "/api/v2/events": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get all", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" } - }, - "/api/v2/projects": { - "get": { - "tags": ["Project"], - "summary": "Get all", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - } - } - } - }, - "post": { - "tags": ["Project"], - "summary": "Create", - "requestBody": { - "description": "The project.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewProject" - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - }, - "400": { - "description": "An error occurred while creating the project." - }, - "409": { - "description": "The project already exists." - } - } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/{organizationId}/projects": { - "get": { - "tags": ["Project"], - "summary": "Get all", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - } - }, - "404": { - "description": "The organization could not be found." - } - } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{id}": { - "get": { - "tags": ["Project"], - "summary": "Get by id", - "operationId": "GetProjectById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } - }, - "patch": { - "tags": ["Project"], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - }, - "400": { - "description": "An error occurred while updating the project." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "put": { - "tags": ["Project"], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewProject" - } - } - } - }, - "400": { - "description": "An error occurred while updating the project." - }, - "404": { - "description": "The project could not be found." - } - } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{ids}": { - "delete": { - "tags": ["Project"], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of project identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WorkInProgressResult" - } - } - } - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more projects were not found." - }, - "500": { - "description": "An error occurred while deleting one or more projects." - } - } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/config": { - "get": { - "tags": ["Project"], - "summary": "Get configuration settings", - "parameters": [ - { - "name": "v", - "in": "query", - "description": "The client configuration version.", - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ClientConfiguration" - } - } - } - }, - "304": { - "description": "The client configuration version is the current version." - }, - "404": { - "description": "The project could not be found." - } - } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" } - }, - "/api/v2/projects/{id}/config": { - "get": { - "tags": ["Project"], - "summary": "Get configuration settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "v", - "in": "query", - "description": "The client configuration version.", - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ClientConfiguration" - } - } - } - }, - "304": { - "description": "The client configuration version is the current version." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "post": { - "tags": ["Project"], - "summary": "Add configuration value", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "query", - "description": "The key name of the configuration object.", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "The configuration value.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid configuration value." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "delete": { - "tags": ["Project"], - "summary": "Remove configuration value", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "query", - "description": "The key name of the configuration object.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid key value." - }, - "404": { - "description": "The project could not be found." - } - } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 } - }, - "/api/v2/projects/{id}/reset-data": { - "get": { - "tags": ["Project"], - "summary": "Reset project data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WorkInProgressResult" - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" } - }, - "/api/v2/users/{userId}/projects/{id}/notifications": { - "get": { - "tags": ["Project"], - "summary": "Get user notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "userId", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } - }, - "put": { - "tags": ["Project"], - "summary": "Set user notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "userId", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The notification settings.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project could not be found." - } - } - }, - "post": { - "tags": ["Project"], - "summary": "Set user notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "userId", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The notification settings.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project could not be found." - } - } - }, - "delete": { - "tags": ["Project"], - "summary": "Remove user notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "userId", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project could not be found." - } - } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{id}/{integration}/notifications": { - "put": { - "tags": ["Project"], - "summary": "Set an integrations notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "integration", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "requestBody": { - "description": "The notification settings.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project or integration could not be found." - }, - "426": { - "description": "Please upgrade your plan to enable integrations." - } - } - }, - "post": { - "tags": ["Project"], - "summary": "Set an integrations notification settings", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "integration", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "requestBody": { - "description": "The notification settings.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotificationSettings" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The project or integration could not be found." - }, - "426": { - "description": "Please upgrade your plan to enable integrations." - } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } } + } } - }, - "/api/v2/projects/{id}/promotedtabs": { - "put": { - "tags": ["Project"], - "summary": "Promote tab", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "name", - "in": "query", - "description": "The tab name.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid tab name." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "post": { - "tags": ["Project"], - "summary": "Promote tab", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "name", - "in": "query", - "description": "The tab name.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid tab name." - }, - "404": { - "description": "The project could not be found." - } - } + }, + "400": { + "description": "Invalid filter." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + }, + "post": { + "tags": [ + "Event" + ], + "summary": "Submit event by POST", + "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", + "parameters": [ + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "string", + "example": "" + } }, - "delete": { - "tags": ["Project"], - "summary": "Demote tab", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "name", - "in": "query", - "description": "The tab name.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid tab name." - }, - "404": { - "description": "The project could not be found." - } - } + "text/plain": { + "schema": { + "type": "string", + "example": "" + } } + }, + "required": true }, - "/api/v2/projects/check-name": { - "get": { - "tags": ["Project"], - "summary": "Check for unique name", - "parameters": [ - { - "name": "name", - "in": "query", - "description": "The project name to check.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "201": { - "description": "The project name is available." - }, - "204": { - "description": "The project name is not available." - } - } + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/organizations/{organizationId}/events": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" } - }, - "/api/v2/organizations/{organizationId}/projects/check-name": { - "get": { - "tags": ["Project"], - "summary": "Check for unique name", - "parameters": [ - { - "name": "name", - "in": "query", - "description": "The project name to check.", - "schema": { - "type": "string" - } - }, - { - "name": "organizationId", - "in": "path", - "description": "If set the check name will be scoped to a specific organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "201": { - "description": "The project name is available." - }, - "204": { - "description": "The project name is not available." - } - } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{id}/data": { - "post": { - "tags": ["Project"], - "summary": "Add custom data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "query", - "description": "The key name of the data object.", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Any string value.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid key or value." - }, - "404": { - "description": "The project could not be found." - } - } - }, - "delete": { - "tags": ["Project"], - "summary": "Remove custom data", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "key", - "in": "query", - "description": "The key name of the data object.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid key or value." - }, - "404": { - "description": "The project could not be found." - } - } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" } - }, - "/api/v2/stacks/{id}": { - "get": { - "tags": ["Stack"], - "summary": "Get by id", - "operationId": "GetStackById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the `time` filter. This is used for time zone support.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Stack" - } - } - } - }, - "404": { - "description": "The stack could not be found." - } - } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" } - }, - "/api/v2/stacks/{ids}/mark-fixed": { - "post": { - "tags": ["Stack"], - "summary": "Mark fixed", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - }, - { - "name": "version", - "in": "query", - "description": "A version number that the stack was fixed in.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "404": { - "description": "One or more stacks could not be found." - } - } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" } - }, - "/api/v2/stacks/{ids}/mark-snoozed": { - "post": { - "tags": ["Stack"], - "summary": "Mark the selected stacks as snoozed", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - }, - { - "name": "snoozeUntilUtc", - "in": "query", - "description": "A time that the stack should be snoozed until.", - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "202": { - "description": "Accepted" - }, - "404": { - "description": "One or more stacks could not be found." - } - } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" } - }, - "/api/v2/stacks/{id}/add-link": { - "post": { - "tags": ["Stack"], - "summary": "Add reference link", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The reference link.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Invalid reference link." - }, - "404": { - "description": "The stack could not be found." - } - } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" } - }, - "/api/v2/stacks/{id}/remove-link": { - "post": { - "tags": ["Stack"], - "summary": "Remove reference link", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The reference link.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StringValueFromBody" - } - } - } - }, - "responses": { - "204": { - "description": "The reference link was removed." - }, - "400": { - "description": "Invalid reference link." - }, - "404": { - "description": "The stack could not be found." - } - } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 } - }, - "/api/v2/stacks/{ids}/mark-critical": { - "post": { - "tags": ["Stack"], - "summary": "Mark future occurrences as critical", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "One or more stacks could not be found." - } - } - }, - "delete": { - "tags": ["Stack"], - "summary": "Mark future occurrences as not critical", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "The stacks were marked as not critical." - }, - "404": { - "description": "One or more stacks could not be found." - } - } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" } - }, - "/api/v2/stacks/{ids}/change-status": { - "post": { - "tags": ["Stack"], - "summary": "Change stack status", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - }, - { - "name": "status", - "in": "query", - "description": "The status that the stack should be changed to.", - "schema": { - "$ref": "#/components/schemas/StackStatus" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "One or more stacks could not be found." - } - } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" } - }, - "/api/v2/stacks/{id}/promote": { - "post": { - "tags": ["Stack"], - "summary": "Promote to external service", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the stack.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The stack could not be found." - }, - "426": { - "description": "Promote to External is a premium feature used to promote an error stack to an external system." - }, - "501": { - "description": "No promoted web hooks are configured for this project." - } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } } + } } - }, - "/api/v2/stacks/{ids}": { - "delete": { - "tags": ["Stack"], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of stack identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WorkInProgressResult" - } - } - } - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more stacks were not found." - }, - "500": { - "description": "An error occurred while deleting one or more stacks." - } - } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The organization could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/events": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" } - }, - "/api/v2/stacks": { - "get": { - "tags": ["Stack"], - "summary": "Get all", - "parameters": [ - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Stack" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - } - } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/{organizationId}/stacks": { - "get": { - "tags": ["Stack"], - "summary": "Get by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Stack" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The organization could not be found." - }, - "426": { - "description": "Unable to view stack occurrences for the suspended organization." - } - } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{projectId}/stacks": { - "get": { - "tags": ["Stack"], - "summary": "Get by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "filter", - "in": "query", - "description": "A filter that controls what data is returned from the server.", - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", - "schema": { - "type": "string" - } - }, - { - "name": "time", - "in": "query", - "description": "The time filter that limits the data being returned to a specific date range.", - "schema": { - "type": "string" - } - }, - { - "name": "offset", - "in": "query", - "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", - "schema": { - "type": "string" - } - }, - { - "name": "mode", - "in": "query", - "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Stack" - } - } - } - } - }, - "400": { - "description": "Invalid filter." - }, - "404": { - "description": "The organization could not be found." - }, - "426": { - "description": "Unable to view stack occurrences for the suspended organization." - } - } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" } - }, - "/api/v2/organizations/{organizationId}/tokens": { - "get": { - "tags": ["Token"], - "summary": "Get by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - } - }, - "404": { - "description": "The organization could not be found." - } - } - }, - "post": { - "tags": ["Token"], - "summary": "Create for organization", - "description": "This is a helper action that makes it easier to create a token for a specific organization.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The token.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewToken" - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while creating the token." - }, - "409": { - "description": "The token already exists." - } - } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{projectId}/tokens": { - "get": { - "tags": ["Token"], - "summary": "Get by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } - }, - "post": { - "tags": ["Token"], - "summary": "Create for project", - "description": "This is a helper action that makes it easier to create a token for a specific project.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The token.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewToken" - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while creating the token." - }, - "404": { - "description": "The project could not be found." - }, - "409": { - "description": "The token already exists." - } - } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{projectId}/tokens/default": { - "get": { - "tags": ["Token"], - "summary": "Get a projects default token", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" } - }, - "/api/v2/tokens/{id}": { - "get": { - "tags": ["Token"], - "summary": "Get by id", - "operationId": "GetTokenById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the token.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "404": { - "description": "The token could not be found." - } - } - }, - "patch": { - "tags": ["Token"], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the token.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while updating the token." - }, - "404": { - "description": "The token could not be found." - } - } - }, - "put": { - "tags": ["Token"], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the token.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while updating the token." - }, - "404": { - "description": "The token could not be found." - } - } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 } - }, - "/api/v2/tokens": { - "post": { - "tags": ["Token"], - "summary": "Create", - "description": "To create a new token, you must specify an organization_id. There are three valid scopes: client, user and admin.", - "requestBody": { - "description": "The token.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewToken" - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewToken" - } - } - } - }, - "400": { - "description": "An error occurred while creating the token." - }, - "409": { - "description": "The token already exists." - } - } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" } - }, - "/api/v2/tokens/{ids}": { - "delete": { - "tags": ["Token"], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of token identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WorkInProgressResult" - } - } - } - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more tokens were not found." - }, - "500": { - "description": "An error occurred while deleting one or more tokens." - } - } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" } - }, - "/api/v2/users/me": { - "get": { - "tags": ["User"], - "summary": "Get current user", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewCurrentUser" - } - } - } - }, - "404": { - "description": "The current user could not be found." - } - } - }, - "delete": { - "tags": ["User"], - "summary": "Delete current user", - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WorkInProgressResult" - } - } - } - }, - "404": { - "description": "The current user could not be found." - } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } } + } } - }, - "/api/v2/users/{id}": { - "get": { - "tags": ["User"], - "summary": "Get by id", - "operationId": "GetUserById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewUser" - } - } - } - }, - "404": { - "description": "The user could not be found." - } - } - }, - "patch": { - "tags": ["User"], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewUser" - } - } - } - }, - "400": { - "description": "An error occurred while updating the user." - }, - "404": { - "description": "The user could not be found." - } - } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + }, + "post": { + "tags": [ + "Event" + ], + "summary": "Submit event by POST for a specific project", + "description": "You can create an event by posting any uncompressed or compressed (gzip or deflate) string or json object. If we know how to handle it\nwe will create a new event. If none of the JSON properties match the event object then we will create a new event and place your JSON\nobject into the events data collection.\n \nYou can also post a multi-line string. We automatically split strings by the \\n character and create a new log event for every line.\n \nSimple event:\n```\n{ \"message\": \"Exceptionless is amazing!\" }\n```\n \nSimple log event with user identity:\n```\n{\n \"type\": \"log\",\n \"message\": \"Exceptionless is amazing!\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@user\":{ \"identity\":\"123456789\", \"name\": \"Test User\" }\n}\n```\n \nMultiple events from string content:\n```\nExceptionless is amazing!\nExceptionless is really amazing!\n```\n \nSimple error:\n```\n{\n \"type\": \"error\",\n \"date\":\"2030-01-01T12:00:00.0000000-05:00\",\n \"@simple_error\": {\n \"message\": \"Simple Exception\",\n \"type\": \"System.Exception\",\n \"stack_trace\": \" at Client.Tests.ExceptionlessClientTests.CanSubmitSimpleException() in ExceptionlessClientTests.cs:line 77\"\n }\n}\n```", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "string", + "example": "" + } }, - "put": { - "tags": ["User"], - "summary": "Update", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "requestBody": { - "description": "The changes", - "content": { - "application/json": { - "schema": { - "description": "A class the tracks changes (i.e. the Delta) for a particular ." - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ViewUser" - } - } - } - }, - "400": { - "description": "An error occurred while updating the user." - }, - "404": { - "description": "The user could not be found." - } - } + "text/plain": { + "schema": { + "type": "string", + "example": "" + } } + }, + "required": true }, - "/api/v2/organizations/{organizationId}/users": { - "get": { - "tags": ["User"], - "summary": "Get by organization", - "parameters": [ - { - "name": "organizationId", - "in": "path", - "description": "The identifier of the organization.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ViewUser" - } - } - } - } - }, - "404": { - "description": "The organization could not be found." - } - } + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/stacks/{stackId}/events": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by stack", + "parameters": [ + { + "name": "stackId", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" } - }, - "/api/v2/users/{ids}": { - "delete": { - "tags": ["User"], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of user identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WorkInProgressResult" - } - } - } - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more users were not found." - }, - "500": { - "description": "An error occurred while deleting one or more users." - } - } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" } - }, - "/api/v2/users/{id}/email-address/{email}": { - "post": { - "tags": ["User"], - "summary": "Update email address", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "email", - "in": "path", - "description": "The new email address.", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateEmailAddressResult" - } - } - } - }, - "400": { - "description": "An error occurred while updating the users email address." - }, - "422": { - "description": "Validation error" - }, - "429": { - "description": "Update email address rate limit reached." - } - } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" } - }, - "/api/v2/users/verify-email-address/{token}": { - "get": { - "tags": ["User"], - "summary": "Verify email address", - "parameters": [ - { - "name": "token", - "in": "path", - "description": "The token identifier.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d-]{24,40}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "404": { - "description": "The user could not be found." - }, - "422": { - "description": "Verify Email Address Token has expired." - } - } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" } - }, - "/api/v2/users/{id}/resend-verification-email": { - "get": { - "tags": ["User"], - "summary": "Resend verification email", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the user.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "The user verification email has been sent." - }, - "404": { - "description": "The user could not be found." - } - } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" } - }, - "/api/v2/projects/{projectId}/webhooks": { - "get": { - "tags": ["WebHook"], - "summary": "Get by project", - "parameters": [ - { - "name": "projectId", - "in": "path", - "description": "The identifier of the project.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "The page parameter is used for pagination. This value must be greater than 0.", - "schema": { - "type": "integer", - "format": "int32", - "default": 1 - } - }, - { - "name": "limit", - "in": "query", - "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/WebHook" - } - } - } - } - }, - "404": { - "description": "The project could not be found." - } - } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" } - }, - "/api/v2/webhooks/{id}": { - "get": { - "tags": ["WebHook"], - "summary": "Get by id", - "operationId": "GetWebHookById", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "The identifier of the web hook.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}$", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebHook" - } - } - } - }, - "404": { - "description": "The web hook could not be found." - } - } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" } - }, - "/api/v2/webhooks": { - "post": { - "tags": ["WebHook"], - "summary": "Create", - "requestBody": { - "description": "The web hook.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewWebHook" - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebHook" - } - } - } - }, - "400": { - "description": "An error occurred while creating the web hook." - }, - "409": { - "description": "The web hook already exists." - } - } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 } - }, - "/api/v2/webhooks/{ids}": { - "delete": { - "tags": ["WebHook"], - "summary": "Remove", - "parameters": [ - { - "name": "ids", - "in": "path", - "description": "A comma-delimited list of web hook identifiers.", - "required": true, - "schema": { - "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WorkInProgressResult" - } - } - } - }, - "400": { - "description": "One or more validation errors occurred." - }, - "404": { - "description": "One or more web hooks were not found." - }, - "500": { - "description": "An error occurred while deleting one or more web hooks." - } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } } + } } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The stack could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } } + } }, - "components": { - "schemas": { - "BillingPlan": { - "required": ["description", "id", "name"], - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "price": { - "type": "number", - "format": "double" - }, - "max_projects": { - "type": "integer", - "format": "int32" - }, - "max_users": { - "type": "integer", - "format": "int32" - }, - "retention_days": { - "type": "integer", - "format": "int32" - }, - "max_events_per_month": { - "type": "integer", - "format": "int32" - }, - "has_premium_features": { - "type": "boolean" - }, - "is_hidden": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "BillingStatus": { - "enum": [0, 1, 2, 3, 4], - "type": "integer", - "format": "int32", - "x-enumNames": [ - "Trialing", - "Active", - "PastDue", - "Canceled", - "Unpaid" - ] - }, - "ChangePasswordModel": { - "required": ["current_password", "password"], - "type": "object", - "properties": { - "current_password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - }, - "password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - } - }, - "additionalProperties": false - }, - "ChangePlanResult": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - }, - "message": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "ClientConfiguration": { - "type": "object", - "properties": { - "version": { - "type": "integer", - "format": "int32" - }, - "settings": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "readOnly": true - } - }, - "additionalProperties": false - }, - "CountResult": { - "type": "object", - "properties": { - "total": { - "type": "integer", - "format": "int64" - }, - "aggregations": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/IAggregate" - }, - "nullable": true - }, - "data": { - "type": "object", - "additionalProperties": { - "nullable": true - }, - "nullable": true - } - }, - "additionalProperties": false - }, - "ExternalAuthInfo": { - "required": ["clientId", "code", "redirectUri"], - "type": "object", - "properties": { - "clientId": { - "minLength": 1, - "type": "string" - }, - "code": { - "minLength": 1, - "type": "string" - }, - "redirectUri": { - "minLength": 1, - "type": "string" - }, - "inviteToken": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "IAggregate": { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": { - "nullable": true - }, - "nullable": true - } - }, - "additionalProperties": false - }, - "Invite": { - "required": ["date_added", "email_address", "token"], - "type": "object", - "properties": { - "token": { - "type": "string" - }, - "email_address": { - "type": "string" - }, - "date_added": { - "type": "string", - "format": "date-time" - } - }, - "additionalProperties": false - }, - "Invoice": { - "required": [ - "date", - "id", - "organization_id", - "organization_name", - "paid", - "total" - ], - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "organization_name": { - "type": "string" - }, - "date": { - "type": "string", - "format": "date-time" - }, - "paid": { - "type": "boolean" - }, - "total": { - "type": "number", - "format": "double" - }, - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/InvoiceLineItem" - } - } - }, - "additionalProperties": false - }, - "InvoiceGridModel": { - "required": ["date", "id", "paid"], - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "date": { - "type": "string", - "format": "date-time" - }, - "paid": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "InvoiceLineItem": { - "required": ["amount", "description"], - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "date": { - "type": "string", - "nullable": true - }, - "amount": { - "type": "number", - "format": "double" - } - }, - "additionalProperties": false - }, - "Login": { - "required": ["email", "password"], - "type": "object", - "properties": { - "email": { - "minLength": 1, - "type": "string", - "description": "The email address or domain username" - }, - "password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - }, - "invite_token": { - "maxLength": 40, - "minLength": 40, - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "NewOrganization": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - }, - "additionalProperties": false - }, - "NewProject": { - "type": "object", - "properties": { - "organization_id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "delete_bot_data_enabled": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "NewToken": { - "type": "object", - "properties": { - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "default_project_id": { - "type": "string", - "nullable": true - }, - "scopes": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "expires_utc": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "notes": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "NewWebHook": { - "type": "object", - "properties": { - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "url": { - "type": "string" - }, - "event_types": { - "type": "array", - "items": { - "type": "string" - } - }, - "version": { - "type": "string", - "description": "The schema version that should be used.", - "nullable": true - } - }, - "additionalProperties": false - }, - "NotificationSettings": { - "type": "object", - "properties": { - "send_daily_summary": { - "type": "boolean" - }, - "report_new_errors": { - "type": "boolean" - }, - "report_critical_errors": { - "type": "boolean" - }, - "report_event_regressions": { - "type": "boolean" - }, - "report_new_events": { - "type": "boolean" - }, - "report_critical_events": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "OAuthAccount": { - "required": ["provider", "provider_user_id", "username"], - "type": "object", - "properties": { - "provider": { - "type": "string" - }, - "provider_user_id": { - "type": "string" - }, - "username": { - "type": "string" - }, - "extra_data": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "readOnly": true - } - }, - "additionalProperties": false - }, - "PersistentEvent": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "stack_id": { - "type": "string" - }, - "is_first_occurrence": { - "type": "boolean" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "idx": { - "type": "object", - "additionalProperties": {} - }, - "type": { - "type": "string", - "nullable": true - }, - "source": { - "type": "string", - "nullable": true - }, - "date": { - "type": "string", - "format": "date-time" - }, - "tags": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - }, - "nullable": true - }, - "message": { - "type": "string", - "nullable": true - }, - "geo": { - "type": "string", - "nullable": true - }, - "value": { - "type": "number", - "format": "double", - "nullable": true - }, - "count": { - "type": "integer", - "format": "int32", - "nullable": true - }, - "data": { - "type": "object", - "additionalProperties": {}, - "nullable": true - }, - "reference_id": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "ResetPasswordModel": { - "required": ["password", "password_reset_token"], - "type": "object", - "properties": { - "password_reset_token": { - "maxLength": 40, - "minLength": 40, - "type": "string" - }, - "password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - } - }, - "additionalProperties": false - }, - "Signup": { - "required": ["email", "name", "password"], - "type": "object", - "properties": { - "name": { - "minLength": 1, - "type": "string" - }, - "email": { - "minLength": 1, - "type": "string", - "description": "The email address or domain username" - }, - "password": { - "maxLength": 100, - "minLength": 6, - "type": "string" - }, - "invite_token": { - "maxLength": 40, - "minLength": 40, - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "Stack": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "status": { - "$ref": "#/components/schemas/StackStatus" - }, - "snooze_until_utc": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "signature_hash": { - "type": "string" - }, - "signature_info": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "fixed_in_version": { - "type": "string", - "nullable": true - }, - "date_fixed": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "title": { - "type": "string" - }, - "total_occurrences": { - "type": "integer", - "format": "int32" - }, - "first_occurrence": { - "type": "string", - "format": "date-time" - }, - "last_occurrence": { - "type": "string", - "format": "date-time" - }, - "description": { - "type": "string", - "nullable": true - }, - "occurrences_are_critical": { - "type": "boolean" - }, - "references": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "duplicate_signature": { - "type": "string" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "updated_utc": { - "type": "string", - "format": "date-time" - }, - "is_deleted": { - "type": "boolean" - }, - "allow_notifications": { - "type": "boolean", - "readOnly": true - } - }, - "additionalProperties": false - }, - "StackStatus": { - "enum": [ - "open", - "fixed", - "regressed", - "snoozed", - "ignored", - "discarded" - ], - "type": "string", - "x-enumNames": [ - "Open", - "Fixed", - "Regressed", - "Snoozed", - "Ignored", - "Discarded" - ] - }, - "StringStringValuesKeyValuePair": { - "type": "object", - "properties": { - "key": { - "type": "string", - "nullable": true - }, - "value": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "StringValueFromBody": { - "type": "object", - "properties": { - "value": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, - "TokenResult": { - "required": ["token"], - "type": "object", - "properties": { - "token": { - "minLength": 1, - "type": "string" - } - }, - "additionalProperties": false - }, - "UpdateEmailAddressResult": { - "required": ["is_verified"], - "type": "object", - "properties": { - "is_verified": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "UsageHourInfo": { - "type": "object", - "properties": { - "date": { - "type": "string", - "format": "date-time" - }, - "total": { - "type": "integer", - "format": "int32" - }, - "blocked": { - "type": "integer", - "format": "int32" - }, - "discarded": { - "type": "integer", - "format": "int32" - }, - "too_big": { - "type": "integer", - "format": "int32" - } - }, - "additionalProperties": false - }, - "UsageInfo": { - "type": "object", - "properties": { - "date": { - "type": "string", - "format": "date-time" - }, - "limit": { - "type": "integer", - "format": "int32" - }, - "total": { - "type": "integer", - "format": "int32" - }, - "blocked": { - "type": "integer", - "format": "int32" - }, - "discarded": { - "type": "integer", - "format": "int32" - }, - "too_big": { - "type": "integer", - "format": "int32" - } - }, - "additionalProperties": false - }, - "User": { - "required": ["email_address", "full_name"], - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_ids": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - }, - "readOnly": true - }, - "password": { - "type": "string", - "nullable": true - }, - "salt": { - "type": "string", - "nullable": true - }, - "password_reset_token": { - "type": "string", - "nullable": true - }, - "password_reset_token_expiration": { - "type": "string", - "format": "date-time" - }, - "o_auth_accounts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/OAuthAccount" - }, - "readOnly": true - }, - "full_name": { - "minLength": 1, - "type": "string" - }, - "email_address": { - "minLength": 1, - "type": "string", - "format": "email" - }, - "email_notifications_enabled": { - "type": "boolean" - }, - "is_email_address_verified": { - "type": "boolean" - }, - "verify_email_address_token": { - "type": "string", - "nullable": true - }, - "verify_email_address_token_expiration": { - "type": "string", - "format": "date-time" - }, - "is_active": { - "type": "boolean" - }, - "roles": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "updated_utc": { - "type": "string", - "format": "date-time" - } - }, - "additionalProperties": false - }, - "UserDescription": { - "type": "object", - "properties": { - "email_address": { - "type": "string", - "nullable": true - }, - "description": { - "type": "string", - "nullable": true - }, - "data": { - "type": "object", - "additionalProperties": {}, - "nullable": true - } - }, - "additionalProperties": false - }, - "ViewCurrentUser": { - "type": "object", - "properties": { - "hash": { - "type": "string", - "nullable": true - }, - "has_local_account": { - "type": "boolean" - }, - "o_auth_accounts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/OAuthAccount" - } - }, - "id": { - "type": "string" - }, - "organization_ids": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "full_name": { - "type": "string" - }, - "email_address": { - "type": "string" - }, - "email_notifications_enabled": { - "type": "boolean" - }, - "is_email_address_verified": { - "type": "boolean" - }, - "is_active": { - "type": "boolean" - }, - "is_invite": { - "type": "boolean" - }, - "roles": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false + "/api/v2/events/by-ref/{referenceId}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by reference id", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/events/by-ref/{referenceId}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get by reference id", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/events/sessions/{sessionId}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of all sessions or events by a session id", + "parameters": [ + { + "name": "sessionId", + "in": "path", + "description": "An identifier that represents a session of events.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/events/sessions/{sessionId}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of by a session id", + "parameters": [ + { + "name": "sessionId", + "in": "path", + "description": "An identifier that represents a session of events.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/events/sessions": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of all sessions", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/organizations/{organizationId}/events/sessions": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of all sessions", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/events/sessions": { + "get": { + "tags": [ + "Event" + ], + "summary": "Get a list of all sessions", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole event object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "before", + "in": "query", + "description": "The before parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "The after parameter is a cursor used for pagination and defines your place in the list of results.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistentEvent" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The project could not be found." + }, + "426": { + "description": "Unable to view event occurrences for the suspended organization." + } + } + } + }, + "/api/v2/events/by-ref/{referenceId}/user-description": { + "post": { + "tags": [ + "Event" + ], + "summary": "Set user description", + "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The user description.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserDescription" + } + } + } + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "Description must be specified." + }, + "404": { + "description": "The event occurrence with the specified reference id could not be found." + } + } + } + }, + "/api/v2/projects/{projectId}/events/by-ref/{referenceId}/user-description": { + "post": { + "tags": [ + "Event" + ], + "summary": "Set user description", + "description": "You can also save an end users contact information and a description of the event. This is really useful for error events as a user can specify reproduction steps in the description.", + "parameters": [ + { + "name": "referenceId", + "in": "path", + "description": "An identifier used that references an event instance.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{8,100}$", + "type": "string" + } + }, + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The user description.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserDescription" + } + } + } + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "Description must be specified." + }, + "404": { + "description": "The event occurrence with the specified reference id could not be found." + } + } + } + }, + "/api/v2/events/session/heartbeat": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit heartbeat", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "The session id or user id.", + "schema": { + "type": "string" + } + }, + { + "name": "close", + "in": "query", + "description": "If true, the session will be closed.", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/events/submit": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit event by GET", + "description": "You can submit an event using an HTTP GET and query string parameters. Any unknown query string parameters will be added to the extended data of the event.\n \nFeature usage named build with a duration of 10:\n```/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "type", + "in": "query", + "description": "The event type (ie. error, log message, feature usage).", + "schema": { + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query string parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/events/submit/{type}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit event type by GET", + "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage event named build with a value of 10:\n```/events/submit/usage?access_token=YOUR_API_KEY&source=build&value=10```\n \nLog event with message, geo and extended data\n```/events/submit/log?access_token=YOUR_API_KEY&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "type", + "in": "path", + "description": "The event type (ie. error, log message, feature usage).", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query string parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/projects/{projectId}/events/submit": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit event type by GET for a specific project", + "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query String parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/projects/{projectId}/events/submit/{type}": { + "get": { + "tags": [ + "Event" + ], + "summary": "Submit event type by GET for a specific project", + "description": "You can submit an event using an HTTP GET and query string parameters.\n \nFeature usage named build with a duration of 10:\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=usage&source=build&value=10```\n \nLog with message, geo and extended data\n```/projects/{projectId}/events/submit?access_token=YOUR_API_KEY&type=log&message=Hello World&source=server01&geo=32.85,-96.9613&randomproperty=true```", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "type", + "in": "path", + "description": "The event type (ie. error, log message, feature usage).", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "source", + "in": "query", + "description": "The event source (ie. machine name, log name, feature name).", + "schema": { + "type": "string" + } + }, + { + "name": "message", + "in": "query", + "description": "The event message.", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "description": "An optional identifier to be used for referencing this event instance at a later time.", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "The date that the event occurred on.", + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "The number of duplicated events.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "value", + "in": "query", + "description": "The value of the event if any.", + "schema": { + "type": "number", + "format": "double" + } + }, + { + "name": "geo", + "in": "query", + "description": "The geo coordinates where the event happened.", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "A list of tags used to categorize this event (comma separated).", + "schema": { + "type": "string" + } + }, + { + "name": "identity", + "in": "query", + "description": "The user's identity that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "identityname", + "in": "query", + "description": "The user's friendly name that the event happened to.", + "schema": { + "type": "string" + } + }, + { + "name": "userAgent", + "in": "header", + "description": "The user agent that submitted the event.", + "schema": { + "type": "string" + } + }, + { + "name": "parameters", + "in": "query", + "description": "Query String parameters that control what properties are set on the event", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StringStringValuesKeyValuePair" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No project id specified and no default project was found." + }, + "404": { + "description": "No project was found." + } + } + } + }, + "/api/v2/events/{ids}": { + "delete": { + "tags": [ + "Event" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of event identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more event occurrences were not found." + }, + "500": { + "description": "An error occurred while deleting one or more event occurrences." + } + } + } + }, + "/api/v2/organizations": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get all", + "parameters": [ + { + "name": "mode", + "in": "query", + "description": "If no mode is set then a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "Organization" + ], + "summary": "Create", + "requestBody": { + "description": "The organization.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewOrganization" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "400": { + "description": "An error occurred while creating the organization." + }, + "409": { + "description": "The organization already exists." + } + } + } + }, + "/api/v2/organizations/{id}": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get by id", + "operationId": "GetOrganizationById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the a lightweight organization object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + }, + "patch": { + "tags": [ + "Organization" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "400": { + "description": "An error occurred while updating the organization." + }, + "404": { + "description": "The organization could not be found." + } + } + }, + "put": { + "tags": [ + "Organization" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewOrganization" + } + } + } + }, + "400": { + "description": "An error occurred while updating the organization." + }, + "404": { + "description": "The organization could not be found." + } + } + } + }, + "/api/v2/organizations/{ids}": { + "delete": { + "tags": [ + "Organization" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of organization identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more organizations were not found." + }, + "500": { + "description": "An error occurred while deleting one or more organizations." + } + } + } + }, + "/api/v2/organizations/invoice/{id}": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get invoice", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the invoice.", + "required": true, + "schema": { + "minLength": 10, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Invoice" + } + } + } + }, + "404": { + "description": "The invoice was not found." + } + } + } + }, + "/api/v2/organizations/{id}/invoices": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get invoices", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "before", + "in": "query", + "description": "A cursor for use in pagination. before is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, starting with obj_bar, your subsequent call can include before=obj_bar in order to fetch the previous page of the list.", + "schema": { + "type": "string" + } + }, + { + "name": "after", + "in": "query", + "description": "A cursor for use in pagination. after is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include after=obj_foo in order to fetch the next page of the list.", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 12 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InvoiceGridModel" + } + } + } + } + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/{id}/plans": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Get plans", + "description": "Gets available plans for a specific organization.", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BillingPlan" + } + } + } + } + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/{id}/change-plan": { + "post": { + "tags": [ + "Organization" + ], + "summary": "Change plan", + "description": "Upgrades or downgrades the organizations plan.", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "planId", + "in": "query", + "description": "The identifier of the plan.", + "schema": { + "type": "string" + } + }, + { + "name": "stripeToken", + "in": "query", + "description": "The token returned from the stripe service.", + "schema": { + "type": "string" + } + }, + { + "name": "last4", + "in": "query", + "description": "The last four numbers of the card.", + "schema": { + "type": "string" + } + }, + { + "name": "couponId", + "in": "query", + "description": "The coupon id.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChangePlanResult" + } + } + } + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/{id}/users/{email}": { + "post": { + "tags": [ + "Organization" + ], + "summary": "Add user", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "email", + "in": "path", + "description": "The email address of the user you wish to add to your organization.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "404": { + "description": "The organization was not found." + }, + "426": { + "description": "Please upgrade your plan to add an additional user." + } + } + }, + "delete": { + "tags": [ + "Organization" + ], + "summary": "Remove user", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "email", + "in": "path", + "description": "The email address of the user you wish to remove from your organization.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "The error occurred while removing the user from your organization" + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/{id}/data/{key}": { + "post": { + "tags": [ + "Organization" + ], + "summary": "Add custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "path", + "description": "The key name of the data object.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "Any string value.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The organization was not found." + } + } + }, + "delete": { + "tags": [ + "Organization" + ], + "summary": "Remove custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "path", + "description": "The key name of the data object.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The organization was not found." + } + } + } + }, + "/api/v2/organizations/check-name": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Check for unique name", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "The organization name to check.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "201": { + "description": "The organization name is available." + }, + "204": { + "description": "The organization name is not available." + } + } + } + }, + "/api/v2/projects": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get all", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Create", + "requestBody": { + "description": "The project.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewProject" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "400": { + "description": "An error occurred while creating the project." + }, + "409": { + "description": "The project already exists." + } + } + } + }, + "/api/v2/organizations/{organizationId}/projects": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get all", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -created returns the results descending by the created date.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + } + }, + "/api/v2/projects/{id}": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get by id", + "operationId": "GetProjectById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the lightweight project object will be returned. If the mode is set to stats than the fully populated object will be returned.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + }, + "patch": { + "tags": [ + "Project" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "400": { + "description": "An error occurred while updating the project." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "put": { + "tags": [ + "Project" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewProject" + } + } + } + }, + "400": { + "description": "An error occurred while updating the project." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/{ids}": { + "delete": { + "tags": [ + "Project" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of project identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more projects were not found." + }, + "500": { + "description": "An error occurred while deleting one or more projects." + } + } + } + }, + "/api/v2/projects/config": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get configuration settings", + "parameters": [ + { + "name": "v", + "in": "query", + "description": "The client configuration version.", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ClientConfiguration" + } + } + } + }, + "304": { + "description": "The client configuration version is the current version." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/{id}/config": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get configuration settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "v", + "in": "query", + "description": "The client configuration version.", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ClientConfiguration" + } + } + } + }, + "304": { + "description": "The client configuration version is the current version." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Add configuration value", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the configuration object.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "The configuration value.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid configuration value." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": [ + "Project" + ], + "summary": "Remove configuration value", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the configuration object.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid key value." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/{id}/reset-data": { + "get": { + "tags": [ + "Project" + ], + "summary": "Reset project data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/users/{userId}/projects/{id}/notifications": { + "get": { + "tags": [ + "Project" + ], + "summary": "Get user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + }, + "put": { + "tags": [ + "Project" + ], + "summary": "Set user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Set user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": [ + "Project" + ], + "summary": "Remove user notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/{id}/{integration}/notifications": { + "put": { + "tags": [ + "Project" + ], + "summary": "Set an integrations notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "integration", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project or integration could not be found." + }, + "426": { + "description": "Please upgrade your plan to enable integrations." + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Set an integrations notification settings", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "integration", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "requestBody": { + "description": "The notification settings.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationSettings" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The project or integration could not be found." + }, + "426": { + "description": "Please upgrade your plan to enable integrations." + } + } + } + }, + "/api/v2/projects/{id}/promotedtabs": { + "put": { + "tags": [ + "Project" + ], + "summary": "Promote tab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "The tab name.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid tab name." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": [ + "Project" + ], + "summary": "Promote tab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "The tab name.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid tab name." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": [ + "Project" + ], + "summary": "Demote tab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "The tab name.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid tab name." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/projects/check-name": { + "get": { + "tags": [ + "Project" + ], + "summary": "Check for unique name", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "The project name to check.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "The project name is available." + }, + "204": { + "description": "The project name is not available." + } + } + } + }, + "/api/v2/organizations/{organizationId}/projects/check-name": { + "get": { + "tags": [ + "Project" + ], + "summary": "Check for unique name", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "The project name to check.", + "schema": { + "type": "string" + } + }, + { + "name": "organizationId", + "in": "path", + "description": "If set the check name will be scoped to a specific organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "The project name is available." + }, + "204": { + "description": "The project name is not available." + } + } + } + }, + "/api/v2/projects/{id}/data": { + "post": { + "tags": [ + "Project" + ], + "summary": "Add custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the data object.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Any string value.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid key or value." + }, + "404": { + "description": "The project could not be found." + } + } + }, + "delete": { + "tags": [ + "Project" + ], + "summary": "Remove custom data", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "The key name of the data object.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid key or value." + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/stacks/{id}": { + "get": { + "tags": [ + "Stack" + ], + "summary": "Get by id", + "operationId": "GetStackById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the `time` filter. This is used for time zone support.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Stack" + } + } + } + }, + "404": { + "description": "The stack could not be found." + } + } + } + }, + "/api/v2/stacks/{ids}/mark-fixed": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Mark fixed", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + }, + { + "name": "version", + "in": "query", + "description": "A version number that the stack was fixed in.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "404": { + "description": "One or more stacks could not be found." + } + } + } + }, + "/api/v2/stacks/{ids}/mark-snoozed": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Mark the selected stacks as snoozed", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + }, + { + "name": "snoozeUntilUtc", + "in": "query", + "description": "A time that the stack should be snoozed until.", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "404": { + "description": "One or more stacks could not be found." + } + } + } + }, + "/api/v2/stacks/{id}/add-link": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Add reference link", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The reference link.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid reference link." + }, + "404": { + "description": "The stack could not be found." + } + } + } + }, + "/api/v2/stacks/{id}/remove-link": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Remove reference link", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The reference link.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StringValueFromBody" + } + } + } + }, + "responses": { + "204": { + "description": "The reference link was removed." + }, + "400": { + "description": "Invalid reference link." + }, + "404": { + "description": "The stack could not be found." + } + } + } + }, + "/api/v2/stacks/{ids}/mark-critical": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Mark future occurrences as critical", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "One or more stacks could not be found." + } + } + }, + "delete": { + "tags": [ + "Stack" + ], + "summary": "Mark future occurrences as not critical", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The stacks were marked as not critical." + }, + "404": { + "description": "One or more stacks could not be found." + } + } + } + }, + "/api/v2/stacks/{ids}/change-status": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Change stack status", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "The status that the stack should be changed to.", + "schema": { + "$ref": "#/components/schemas/StackStatus" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "One or more stacks could not be found." + } + } + } + }, + "/api/v2/stacks/{id}/promote": { + "post": { + "tags": [ + "Stack" + ], + "summary": "Promote to external service", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the stack.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The stack could not be found." + }, + "426": { + "description": "Promote to External is a premium feature used to promote an error stack to an external system." + }, + "501": { + "description": "No promoted web hooks are configured for this project." + } + } + } + }, + "/api/v2/stacks/{ids}": { + "delete": { + "tags": [ + "Stack" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of stack identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more stacks were not found." + }, + "500": { + "description": "An error occurred while deleting one or more stacks." + } + } + } + }, + "/api/v2/stacks": { + "get": { + "tags": [ + "Stack" + ], + "summary": "Get all", + "parameters": [ + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + } + } + } + }, + "/api/v2/organizations/{organizationId}/stacks": { + "get": { + "tags": [ + "Stack" + ], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The organization could not be found." + }, + "426": { + "description": "Unable to view stack occurrences for the suspended organization." + } + } + } + }, + "/api/v2/projects/{projectId}/stacks": { + "get": { + "tags": [ + "Stack" + ], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "A filter that controls what data is returned from the server.", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Controls the sort order that the data is returned in. In this example -date returns the results descending by date.", + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "The time filter that limits the data being returned to a specific date range.", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "in": "query", + "description": "The time offset in minutes that controls what data is returned based on the time filter. This is used for time zone support.", + "schema": { + "type": "string" + } + }, + { + "name": "mode", + "in": "query", + "description": "If no mode is set then the whole stack object will be returned. If the mode is set to summary than a lightweight object will be returned.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Stack" + } + } + } + } + }, + "400": { + "description": "Invalid filter." + }, + "404": { + "description": "The organization could not be found." + }, + "426": { + "description": "Unable to view stack occurrences for the suspended organization." + } + } + } + }, + "/api/v2/organizations/{organizationId}/tokens": { + "get": { + "tags": [ + "Token" + ], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + }, + "post": { + "tags": [ + "Token" + ], + "summary": "Create for organization", + "description": "This is a helper action that makes it easier to create a token for a specific organization.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewToken" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while creating the token." + }, + "409": { + "description": "The token already exists." + } + } + } + }, + "/api/v2/projects/{projectId}/tokens": { + "get": { + "tags": [ + "Token" + ], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + }, + "post": { + "tags": [ + "Token" + ], + "summary": "Create for project", + "description": "This is a helper action that makes it easier to create a token for a specific project.\nYou may also specify a scope when creating a token. There are three valid scopes: client, user and admin.", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewToken" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while creating the token." + }, + "404": { + "description": "The project could not be found." + }, + "409": { + "description": "The token already exists." + } + } + } + }, + "/api/v2/projects/{projectId}/tokens/default": { + "get": { + "tags": [ + "Token" + ], + "summary": "Get a projects default token", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/tokens/{id}": { + "get": { + "tags": [ + "Token" + ], + "summary": "Get by id", + "operationId": "GetTokenById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the token.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "404": { + "description": "The token could not be found." + } + } + }, + "patch": { + "tags": [ + "Token" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the token.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while updating the token." + }, + "404": { + "description": "The token could not be found." + } + } + }, + "put": { + "tags": [ + "Token" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the token.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while updating the token." + }, + "404": { + "description": "The token could not be found." + } + } + } + }, + "/api/v2/tokens": { + "post": { + "tags": [ + "Token" + ], + "summary": "Create", + "description": "To create a new token, you must specify an organization_id. There are three valid scopes: client, user and admin.", + "requestBody": { + "description": "The token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewToken" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewToken" + } + } + } + }, + "400": { + "description": "An error occurred while creating the token." + }, + "409": { + "description": "The token already exists." + } + } + } + }, + "/api/v2/tokens/{ids}": { + "delete": { + "tags": [ + "Token" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of token identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}(,[a-zA-Z\\d-]{24,40})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more tokens were not found." + }, + "500": { + "description": "An error occurred while deleting one or more tokens." + } + } + } + }, + "/api/v2/users/me": { + "get": { + "tags": [ + "User" + ], + "summary": "Get current user", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewCurrentUser" + } + } + } + }, + "404": { + "description": "The current user could not be found." + } + } + }, + "delete": { + "tags": [ + "User" + ], + "summary": "Delete current user", + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "404": { + "description": "The current user could not be found." + } + } + } + }, + "/api/v2/users/{id}": { + "get": { + "tags": [ + "User" + ], + "summary": "Get by id", + "operationId": "GetUserById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + }, + "404": { + "description": "The user could not be found." + } + } + }, + "patch": { + "tags": [ + "User" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + }, + "400": { + "description": "An error occurred while updating the user." + }, + "404": { + "description": "The user could not be found." + } + } + }, + "put": { + "tags": [ + "User" + ], + "summary": "Update", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "requestBody": { + "description": "The changes", + "content": { + "application/json": { + "schema": { + "description": "A class the tracks changes (i.e. the Delta) for a particular ." + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + }, + "400": { + "description": "An error occurred while updating the user." + }, + "404": { + "description": "The user could not be found." + } + } + } + }, + "/api/v2/organizations/{organizationId}/users": { + "get": { + "tags": [ + "User" + ], + "summary": "Get by organization", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "The identifier of the organization.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ViewUser" + } + } + } + } + }, + "404": { + "description": "The organization could not be found." + } + } + } + }, + "/api/v2/users/{ids}": { + "delete": { + "tags": [ + "User" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of user identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more users were not found." + }, + "500": { + "description": "An error occurred while deleting one or more users." + } + } + } + }, + "/api/v2/users/{id}/email-address/{email}": { + "post": { + "tags": [ + "User" + ], + "summary": "Update email address", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "email", + "in": "path", + "description": "The new email address.", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateEmailAddressResult" + } + } + } + }, + "400": { + "description": "An error occurred while updating the users email address." + }, + "422": { + "description": "Validation error" + }, + "429": { + "description": "Update email address rate limit reached." + } + } + } + }, + "/api/v2/users/verify-email-address/{token}": { + "get": { + "tags": [ + "User" + ], + "summary": "Verify email address", + "parameters": [ + { + "name": "token", + "in": "path", + "description": "The token identifier.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d-]{24,40}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "The user could not be found." + }, + "422": { + "description": "Verify Email Address Token has expired." + } + } + } + }, + "/api/v2/users/{id}/resend-verification-email": { + "get": { + "tags": [ + "User" + ], + "summary": "Resend verification email", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the user.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "The user verification email has been sent." + }, + "404": { + "description": "The user could not be found." + } + } + } + }, + "/api/v2/projects/{projectId}/webhooks": { + "get": { + "tags": [ + "WebHook" + ], + "summary": "Get by project", + "parameters": [ + { + "name": "projectId", + "in": "path", + "description": "The identifier of the project.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "The page parameter is used for pagination. This value must be greater than 0.", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "limit", + "in": "query", + "description": "A limit on the number of objects to be returned. Limit can range between 1 and 100 items.", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebHook" + } + } + } + } + }, + "404": { + "description": "The project could not be found." + } + } + } + }, + "/api/v2/webhooks/{id}": { + "get": { + "tags": [ + "WebHook" + ], + "summary": "Get by id", + "operationId": "GetWebHookById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "The identifier of the web hook.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}$", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebHook" + } + } + } + }, + "404": { + "description": "The web hook could not be found." + } + } + } + }, + "/api/v2/webhooks": { + "post": { + "tags": [ + "WebHook" + ], + "summary": "Create", + "requestBody": { + "description": "The web hook.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewWebHook" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebHook" + } + } + } + }, + "400": { + "description": "An error occurred while creating the web hook." + }, + "409": { + "description": "The web hook already exists." + } + } + } + }, + "/api/v2/webhooks/{ids}": { + "delete": { + "tags": [ + "WebHook" + ], + "summary": "Remove", + "parameters": [ + { + "name": "ids", + "in": "path", + "description": "A comma-delimited list of web hook identifiers.", + "required": true, + "schema": { + "pattern": "^[a-zA-Z\\d]{24,36}(,[a-zA-Z\\d]{24,36})*$", + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkInProgressResult" + } + } + } + }, + "400": { + "description": "One or more validation errors occurred." + }, + "404": { + "description": "One or more web hooks were not found." + }, + "500": { + "description": "An error occurred while deleting one or more web hooks." + } + } + } + } + }, + "components": { + "schemas": { + "BillingPlan": { + "required": [ + "description", + "id", + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "price": { + "type": "number", + "format": "double" + }, + "max_projects": { + "type": "integer", + "format": "int32" + }, + "max_users": { + "type": "integer", + "format": "int32" + }, + "retention_days": { + "type": "integer", + "format": "int32" + }, + "max_events_per_month": { + "type": "integer", + "format": "int32" + }, + "has_premium_features": { + "type": "boolean" + }, + "is_hidden": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "BillingStatus": { + "enum": [ + 0, + 1, + 2, + 3, + 4 + ], + "type": "integer", + "format": "int32", + "x-enumNames": [ + "Trialing", + "Active", + "PastDue", + "Canceled", + "Unpaid" + ] + }, + "ChangePasswordModel": { + "required": [ + "current_password", + "password" + ], + "type": "object", + "properties": { + "current_password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + } + }, + "additionalProperties": false + }, + "ChangePlanResult": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "message": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "ClientConfiguration": { + "type": "object", + "properties": { + "version": { + "type": "integer", + "format": "int32" + }, + "settings": { + "type": "object", + "additionalProperties": { + "type": "string" }, - "ViewOrganization": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "name": { - "type": "string" - }, - "plan_id": { - "type": "string" - }, - "plan_name": { - "type": "string" - }, - "plan_description": { - "type": "string" - }, - "card_last4": { - "type": "string", - "nullable": true - }, - "subscribe_date": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "billing_change_date": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "billing_changed_by_user_id": { - "type": "string", - "nullable": true - }, - "billing_status": { - "$ref": "#/components/schemas/BillingStatus" - }, - "billing_price": { - "type": "number", - "format": "double" - }, - "max_events_per_month": { - "type": "integer", - "format": "int32" - }, - "bonus_events_per_month": { - "type": "integer", - "format": "int32" - }, - "bonus_expiration": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "retention_days": { - "type": "integer", - "format": "int32" - }, - "is_suspended": { - "type": "boolean" - }, - "suspension_code": { - "type": "string", - "nullable": true - }, - "suspension_notes": { - "type": "string", - "nullable": true - }, - "suspension_date": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "has_premium_features": { - "type": "boolean" - }, - "max_users": { - "type": "integer", - "format": "int32" - }, - "max_projects": { - "type": "integer", - "format": "int32" - }, - "project_count": { - "type": "integer", - "format": "int64" - }, - "stack_count": { - "type": "integer", - "format": "int64" - }, - "event_count": { - "type": "integer", - "format": "int64" - }, - "invites": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Invite" - } - }, - "usage_hours": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UsageHourInfo" - } - }, - "usage": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UsageInfo" - } - }, - "data": { - "type": "object", - "additionalProperties": {}, - "nullable": true - }, - "is_throttled": { - "type": "boolean" - }, - "is_over_monthly_limit": { - "type": "boolean" - }, - "is_over_request_limit": { - "type": "boolean" - } - }, - "additionalProperties": false + "readOnly": true + } + }, + "additionalProperties": false + }, + "CountResult": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int64" + }, + "aggregations": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/IAggregate" }, - "ViewProject": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "organization_id": { - "type": "string" - }, - "organization_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "delete_bot_data_enabled": { - "type": "boolean" - }, - "data": { - "type": "object", - "additionalProperties": {}, - "nullable": true - }, - "promoted_tabs": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "is_configured": { - "type": "boolean", - "nullable": true - }, - "stack_count": { - "type": "integer", - "format": "int64" - }, - "event_count": { - "type": "integer", - "format": "int64" - }, - "has_premium_features": { - "type": "boolean" - }, - "has_slack_integration": { - "type": "boolean" - }, - "usage_hours": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UsageHourInfo" - } - }, - "usage": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UsageInfo" - } - } - }, - "additionalProperties": false + "nullable": true + }, + "data": { + "type": "object", + "additionalProperties": { + "nullable": true }, - "ViewToken": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "user_id": { - "type": "string", - "nullable": true - }, - "default_project_id": { - "type": "string", - "nullable": true - }, - "scopes": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "expires_utc": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "notes": { - "type": "string", - "nullable": true - }, - "is_disabled": { - "type": "boolean" - }, - "is_suspended": { - "type": "boolean" - }, - "created_utc": { - "type": "string", - "format": "date-time" - }, - "updated_utc": { - "type": "string", - "format": "date-time" - } - }, - "additionalProperties": false + "nullable": true + } + }, + "additionalProperties": false + }, + "ExternalAuthInfo": { + "required": [ + "clientId", + "code", + "redirectUri" + ], + "type": "object", + "properties": { + "clientId": { + "minLength": 1, + "type": "string" + }, + "code": { + "minLength": 1, + "type": "string" + }, + "redirectUri": { + "minLength": 1, + "type": "string" + }, + "inviteToken": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "IAggregate": { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "nullable": true }, - "ViewUser": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_ids": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - }, - "full_name": { - "type": "string" - }, - "email_address": { - "type": "string" - }, - "email_notifications_enabled": { - "type": "boolean" - }, - "is_email_address_verified": { - "type": "boolean" - }, - "is_active": { - "type": "boolean" - }, - "is_invite": { - "type": "boolean" - }, - "roles": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false + "nullable": true + } + }, + "additionalProperties": false + }, + "Invite": { + "required": [ + "date_added", + "email_address", + "token" + ], + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "email_address": { + "type": "string" + }, + "date_added": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "Invoice": { + "required": [ + "date", + "id", + "organization_id", + "organization_name", + "paid", + "total" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "organization_name": { + "type": "string" + }, + "date": { + "type": "string", + "format": "date-time" + }, + "paid": { + "type": "boolean" + }, + "total": { + "type": "number", + "format": "double" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InvoiceLineItem" + } + } + }, + "additionalProperties": false + }, + "InvoiceGridModel": { + "required": [ + "date", + "id", + "paid" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "date": { + "type": "string", + "format": "date-time" + }, + "paid": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "InvoiceLineItem": { + "required": [ + "amount", + "description" + ], + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "date": { + "type": "string", + "nullable": true + }, + "amount": { + "type": "number", + "format": "double" + } + }, + "additionalProperties": false + }, + "Login": { + "required": [ + "email", + "password" + ], + "type": "object", + "properties": { + "email": { + "minLength": 1, + "type": "string", + "description": "The email address or domain username" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + }, + "invite_token": { + "maxLength": 40, + "minLength": 40, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "NewOrganization": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NewProject": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "delete_bot_data_enabled": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "NewToken": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "default_project_id": { + "type": "string", + "nullable": true + }, + "scopes": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "expires_utc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "notes": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "NewWebHook": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "url": { + "type": "string" + }, + "event_types": { + "type": "array", + "items": { + "type": "string" + } + }, + "version": { + "type": "string", + "description": "The schema version that should be used.", + "nullable": true + } + }, + "additionalProperties": false + }, + "NotificationSettings": { + "type": "object", + "properties": { + "send_daily_summary": { + "type": "boolean" + }, + "report_new_errors": { + "type": "boolean" + }, + "report_critical_errors": { + "type": "boolean" + }, + "report_event_regressions": { + "type": "boolean" + }, + "report_new_events": { + "type": "boolean" + }, + "report_critical_events": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "OAuthAccount": { + "required": [ + "provider", + "provider_user_id", + "username" + ], + "type": "object", + "properties": { + "provider": { + "type": "string" + }, + "provider_user_id": { + "type": "string" + }, + "username": { + "type": "string" + }, + "extra_data": { + "type": "object", + "additionalProperties": { + "type": "string" }, - "WebHook": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organization_id": { - "type": "string" - }, - "project_id": { - "type": "string" - }, - "url": { - "type": "string" - }, - "event_types": { - "type": "array", - "items": { - "type": "string" - } - }, - "is_enabled": { - "type": "boolean" - }, - "version": { - "type": "string" - }, - "created_utc": { - "type": "string", - "format": "date-time" - } - }, - "additionalProperties": false + "readOnly": true + } + }, + "additionalProperties": false + }, + "PersistentEvent": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "stack_id": { + "type": "string" + }, + "is_first_occurrence": { + "type": "boolean" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "idx": { + "type": "object", + "additionalProperties": { } + }, + "type": { + "type": "string", + "nullable": true + }, + "source": { + "type": "string", + "nullable": true + }, + "date": { + "type": "string", + "format": "date-time" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" }, - "WorkInProgressResult": { - "type": "object", - "properties": { - "workers": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false + "nullable": true + }, + "message": { + "type": "string", + "nullable": true + }, + "geo": { + "type": "string", + "nullable": true + }, + "value": { + "type": "number", + "format": "double", + "nullable": true + }, + "count": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "data": { + "type": "object", + "additionalProperties": { }, + "nullable": true + }, + "reference_id": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "ResetPasswordModel": { + "required": [ + "password", + "password_reset_token" + ], + "type": "object", + "properties": { + "password_reset_token": { + "maxLength": 40, + "minLength": 40, + "type": "string" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + } + }, + "additionalProperties": false + }, + "Signup": { + "required": [ + "email", + "name", + "password" + ], + "type": "object", + "properties": { + "name": { + "minLength": 1, + "type": "string" + }, + "email": { + "minLength": 1, + "type": "string", + "description": "The email address or domain username" + }, + "password": { + "maxLength": 100, + "minLength": 6, + "type": "string" + }, + "invite_token": { + "maxLength": 40, + "minLength": 40, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "Stack": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/StackStatus" + }, + "snooze_until_utc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "signature_hash": { + "type": "string" + }, + "signature_info": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "fixed_in_version": { + "type": "string", + "nullable": true + }, + "date_fixed": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "title": { + "type": "string" + }, + "total_occurrences": { + "type": "integer", + "format": "int32" + }, + "first_occurrence": { + "type": "string", + "format": "date-time" + }, + "last_occurrence": { + "type": "string", + "format": "date-time" + }, + "description": { + "type": "string", + "nullable": true + }, + "occurrences_are_critical": { + "type": "boolean" + }, + "references": { + "type": "array", + "items": { + "type": "string" } + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "duplicate_signature": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "updated_utc": { + "type": "string", + "format": "date-time" + }, + "is_deleted": { + "type": "boolean" + }, + "allow_notifications": { + "type": "boolean", + "readOnly": true + } + }, + "additionalProperties": false + }, + "StackStatus": { + "enum": [ + "open", + "fixed", + "regressed", + "snoozed", + "ignored", + "discarded" + ], + "type": "string", + "x-enumNames": [ + "Open", + "Fixed", + "Regressed", + "Snoozed", + "Ignored", + "Discarded" + ] + }, + "StringStringValuesKeyValuePair": { + "type": "object", + "properties": { + "key": { + "type": "string", + "nullable": true + }, + "value": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "StringValueFromBody": { + "type": "object", + "properties": { + "value": { + "type": "string", + "nullable": true + } }, - "securitySchemes": { - "Basic": { - "type": "http", - "description": "Basic HTTP Authentication", - "scheme": "basic" + "additionalProperties": false + }, + "TokenResult": { + "required": [ + "token" + ], + "type": "object", + "properties": { + "token": { + "minLength": 1, + "type": "string" + } + }, + "additionalProperties": false + }, + "UpdateEmailAddressResult": { + "required": [ + "is_verified" + ], + "type": "object", + "properties": { + "is_verified": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "UsageHourInfo": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "total": { + "type": "integer", + "format": "int32" + }, + "blocked": { + "type": "integer", + "format": "int32" + }, + "discarded": { + "type": "integer", + "format": "int32" + }, + "too_big": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "UsageInfo": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "limit": { + "type": "integer", + "format": "int32" + }, + "total": { + "type": "integer", + "format": "int32" + }, + "blocked": { + "type": "integer", + "format": "int32" + }, + "discarded": { + "type": "integer", + "format": "int32" + }, + "too_big": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "User": { + "required": [ + "email_address", + "full_name" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_ids": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" }, - "Bearer": { - "type": "http", - "description": "Authorization token. Example: \"Bearer {apikey}\"", - "scheme": "bearer" + "readOnly": true + }, + "password": { + "type": "string", + "nullable": true + }, + "salt": { + "type": "string", + "nullable": true + }, + "password_reset_token": { + "type": "string", + "nullable": true + }, + "password_reset_token_expiration": { + "type": "string", + "format": "date-time" + }, + "o_auth_accounts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OAuthAccount" }, - "Token": { - "type": "apiKey", - "description": "Authorization token. Example: \"Bearer {apikey}\"", - "name": "access_token", - "in": "query" + "readOnly": true + }, + "full_name": { + "minLength": 1, + "type": "string" + }, + "email_address": { + "minLength": 1, + "type": "string", + "format": "email" + }, + "email_notifications_enabled": { + "type": "boolean" + }, + "is_email_address_verified": { + "type": "boolean" + }, + "verify_email_address_token": { + "type": "string", + "nullable": true + }, + "verify_email_address_token_expiration": { + "type": "string", + "format": "date-time" + }, + "is_active": { + "type": "boolean" + }, + "roles": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" } - } - }, - "security": [ - { - "Basic": [], - "Bearer": [], - "Token": [] - } - ], - "tags": [ - { - "name": "Auth" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "updated_utc": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "UserDescription": { + "type": "object", + "properties": { + "email_address": { + "type": "string", + "nullable": true + }, + "description": { + "type": "string", + "nullable": true + }, + "data": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } }, - { - "name": "Event" + "additionalProperties": false + }, + "ViewCurrentUser": { + "type": "object", + "properties": { + "hash": { + "type": "string", + "nullable": true + }, + "has_local_account": { + "type": "boolean" + }, + "o_auth_accounts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OAuthAccount" + } + }, + "id": { + "type": "string" + }, + "organization_ids": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "full_name": { + "type": "string" + }, + "email_address": { + "type": "string" + }, + "email_notifications_enabled": { + "type": "boolean" + }, + "is_email_address_verified": { + "type": "boolean" + }, + "is_active": { + "type": "boolean" + }, + "is_invite": { + "type": "boolean" + }, + "roles": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "ViewOrganization": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "plan_id": { + "type": "string" + }, + "plan_name": { + "type": "string" + }, + "plan_description": { + "type": "string" + }, + "card_last4": { + "type": "string", + "nullable": true + }, + "subscribe_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "billing_change_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "billing_changed_by_user_id": { + "type": "string", + "nullable": true + }, + "billing_status": { + "$ref": "#/components/schemas/BillingStatus" + }, + "billing_price": { + "type": "number", + "format": "double" + }, + "max_events_per_month": { + "type": "integer", + "format": "int32" + }, + "bonus_events_per_month": { + "type": "integer", + "format": "int32" + }, + "bonus_expiration": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "retention_days": { + "type": "integer", + "format": "int32" + }, + "is_suspended": { + "type": "boolean" + }, + "suspension_code": { + "type": "string", + "nullable": true + }, + "suspension_notes": { + "type": "string", + "nullable": true + }, + "suspension_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "has_premium_features": { + "type": "boolean" + }, + "max_users": { + "type": "integer", + "format": "int32" + }, + "max_projects": { + "type": "integer", + "format": "int32" + }, + "project_count": { + "type": "integer", + "format": "int64" + }, + "stack_count": { + "type": "integer", + "format": "int64" + }, + "event_count": { + "type": "integer", + "format": "int64" + }, + "invites": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Invite" + } + }, + "usage_hours": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageHourInfo" + } + }, + "usage": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageInfo" + } + }, + "data": { + "type": "object", + "additionalProperties": { }, + "nullable": true + }, + "is_throttled": { + "type": "boolean" + }, + "is_over_monthly_limit": { + "type": "boolean" + }, + "is_over_request_limit": { + "type": "boolean" + } }, - { - "name": "Organization" + "additionalProperties": false + }, + "ViewProject": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "organization_id": { + "type": "string" + }, + "organization_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "delete_bot_data_enabled": { + "type": "boolean" + }, + "data": { + "type": "object", + "additionalProperties": { }, + "nullable": true + }, + "promoted_tabs": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "is_configured": { + "type": "boolean", + "nullable": true + }, + "stack_count": { + "type": "integer", + "format": "int64" + }, + "event_count": { + "type": "integer", + "format": "int64" + }, + "has_premium_features": { + "type": "boolean" + }, + "has_slack_integration": { + "type": "boolean" + }, + "usage_hours": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageHourInfo" + } + }, + "usage": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageInfo" + } + } }, - { - "name": "Project" + "additionalProperties": false + }, + "ViewToken": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "user_id": { + "type": "string", + "nullable": true + }, + "default_project_id": { + "type": "string", + "nullable": true + }, + "scopes": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "expires_utc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "notes": { + "type": "string", + "nullable": true + }, + "is_disabled": { + "type": "boolean" + }, + "is_suspended": { + "type": "boolean" + }, + "created_utc": { + "type": "string", + "format": "date-time" + }, + "updated_utc": { + "type": "string", + "format": "date-time" + } }, - { - "name": "Stack" + "additionalProperties": false + }, + "ViewUser": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_ids": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "full_name": { + "type": "string" + }, + "email_address": { + "type": "string" + }, + "email_notifications_enabled": { + "type": "boolean" + }, + "is_email_address_verified": { + "type": "boolean" + }, + "is_active": { + "type": "boolean" + }, + "is_invite": { + "type": "boolean" + }, + "roles": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } }, - { - "name": "Token" + "additionalProperties": false + }, + "WebHook": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "url": { + "type": "string" + }, + "event_types": { + "type": "array", + "items": { + "type": "string" + } + }, + "is_enabled": { + "type": "boolean" + }, + "version": { + "type": "string" + }, + "created_utc": { + "type": "string", + "format": "date-time" + } }, - { - "name": "User" + "additionalProperties": false + }, + "WorkInProgressResult": { + "type": "object", + "properties": { + "workers": { + "type": "array", + "items": { + "type": "string" + } + } }, - { - "name": "WebHook" - } - ] + "additionalProperties": false + } + }, + "securitySchemes": { + "Basic": { + "type": "http", + "description": "Basic HTTP Authentication", + "scheme": "basic" + }, + "Bearer": { + "type": "http", + "description": "Authorization token. Example: \"Bearer {apikey}\"", + "scheme": "bearer" + }, + "Token": { + "type": "apiKey", + "description": "Authorization token. Example: \"Bearer {apikey}\"", + "name": "access_token", + "in": "query" + } + } + }, + "security": [ + { + "Basic": [ ], + "Bearer": [ ], + "Token": [ ] + } + ], + "tags": [ + { + "name": "Auth" + }, + { + "name": "Event" + }, + { + "name": "Organization" + }, + { + "name": "Project" + }, + { + "name": "Stack" + }, + { + "name": "Token" + }, + { + "name": "User" + }, + { + "name": "WebHook" + } + ] }