{"id":217,"date":"2025-11-04T08:50:24","date_gmt":"2025-11-04T06:50:24","guid":{"rendered":"https:\/\/www.insync.co.za\/blog\/?p=217"},"modified":"2025-11-04T09:15:15","modified_gmt":"2025-11-04T07:15:15","slug":"mastering-asp-net-core-health-checks-with-ui-a-deep-dive","status":"publish","type":"post","link":"https:\/\/www.insync.co.za\/blog\/2025\/11\/04\/mastering-asp-net-core-health-checks-with-ui-a-deep-dive\/","title":{"rendered":"Mastering ASP.NET Core Health Checks (with UI) \u2014 A Deep Dive"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Based on the official Microsoft documentation on health checks in ASP.NET Core <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/host-and-deploy\/health-checks?view=aspnetcore-9.0&amp;utm_source=chatgpt.com\" target=\"_blank\" rel=\"noreferrer noopener\">Microsoft Learn<\/a><br>Plus extensions like HealthChecks.UI from the open-source community <a href=\"https:\/\/github.com\/Xabaril\/AspNetCore.Diagnostics.HealthChecks?utm_source=chatgpt.com\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub<\/a><\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Introduction<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In modern web APIs, it&#8217;s essential to have self-monitoring baked in. Health checks let your application report its own status, so:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Load balancers or container orchestrators (Kubernetes, Azure App Service, etc.) can detect when an instance is unhealthy and stop routing traffic to it. <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/host-and-deploy\/health-checks?view=aspnetcore-9.0&amp;utm_source=chatgpt.com\" target=\"_blank\" rel=\"noreferrer noopener\">Microsoft Learn<\/a><\/li>\n\n\n\n<li>Monitoring systems (Prometheus, Grafana, Application Insights, etc.) can query health endpoints to alert you before users notice. <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/architecture\/microservices\/implement-resilient-applications\/monitor-app-health?utm_source=chatgpt.com\" target=\"_blank\" rel=\"noreferrer noopener\">Microsoft Learn<\/a><\/li>\n\n\n\n<li>Developers and ops teams get visibility into dependencies (database, cache, external APIs).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This blog covers:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Basic health check setup<\/li>\n\n\n\n<li>Built-in and community health checks<\/li>\n\n\n\n<li>Custom health checks<\/li>\n\n\n\n<li>Advanced endpoint configurations (filtering, readiness\/liveness)<\/li>\n\n\n\n<li>HealthChecks UI for visualization<\/li>\n\n\n\n<li>Best practices &amp; tips<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Basic Health Probe (Liveness)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">By default, ASP.NET Core includes health check middleware (via <code>Microsoft.AspNetCore.Diagnostics.HealthChecks<\/code>). The process is:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Register health check services with <code>AddHealthChecks()<\/code><\/li>\n\n\n\n<li>Map a health endpoint using <code>MapHealthChecks(...)<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s the minimal setup in <code>Program.cs<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-94d8345ea12a21adfd4d67ff1f1f2113\"><code>var builder = WebApplication.CreateBuilder(args);\n\n\/\/ Register health check services\nbuilder.Services.AddHealthChecks();\n\nvar app = builder.Build();\n\n\/\/ Map a health endpoint\napp.MapHealthChecks(\"\/healthz\");\n\napp.Run();\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With no specific health checks registered, the health endpoint returns <strong>Healthy<\/strong> (HTTP 200) as long as the app is running.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The default response is plaintext showing <code>Healthy<\/code>, <code>Degraded<\/code> or <code>Unhealthy<\/code> (from the <code>HealthStatus<\/code> enum). <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Healthy<\/code> \u2192 HTTP 200<\/li>\n\n\n\n<li><code>Degraded<\/code> \u2192 HTTP 200 (by default)<\/li>\n\n\n\n<li><code>Unhealthy<\/code> \u2192 HTTP 503 (Service Unavailable) <\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You can customize HTTP status codes and output using <code>HealthCheckOptions<\/code> when mapping.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Built-In &amp; Community Health Checks<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Microsoft \/ Core health checks<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">ASP.NET Core\u2019s built-in library primarily gives the infrastructure for health checks (middleware, interfaces). For particular subsystems (SQL, Redis, etc.), you often rely on external packages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But there <em>is<\/em> a \u201csystem\u201d health check package:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>AspNetCore.HealthChecks.System<\/strong> \u2014 for system-level checks (e.g., disk space) <a href=\"https:\/\/www.nuget.org\/packages\/AspNetCore.HealthChecks.System?utm_source=chatgpt.com\" target=\"_blank\" rel=\"noreferrer noopener\">NuGet<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Community \/ Diagnostic HealthChecks by Xabaril<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>AspNetCore.Diagnostics.HealthChecks<\/strong> library (open source) provides a suite of ready checks for many common dependencies. <a href=\"https:\/\/github.com\/Xabaril\/AspNetCore.Diagnostics.HealthChecks?utm_source=chatgpt.com\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Examples include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SQL Server (<code>AddSqlServer(...)<\/code>)<\/li>\n\n\n\n<li>EF Core (via Microsoft\u2019s diagnostics or via the package)<\/li>\n\n\n\n<li>Redis (<code>AddRedis(...)<\/code>)<\/li>\n\n\n\n<li>URL\/URI endpoints (<code>AddUrlGroup(...)<\/code>)<\/li>\n\n\n\n<li>Disk or system checks (<code>AddDiskStorageHealthCheck(...)<\/code>)<\/li>\n\n\n\n<li>TCP \/ socket checks, MongoDB, RabbitMQ, Azure services, etc.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">These reduce boilerplate and speed setup. <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/architecture\/microservices\/implement-resilient-applications\/monitor-app-health?utm_source=chatgpt.com\" target=\"_blank\" rel=\"noreferrer noopener\">Microsoft Learn<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Custom Health Checks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If your application has specialized dependencies (e.g. email service, third-party API, custom business logic), you can implement your own health check via <code>IHealthCheck<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-1ae0d6b9762dc4baef03245a3e3eff16\"><code>public class EmailServiceHealthCheck : IHealthCheck\n{\n    private readonly IEmailService _emailService;\n\n    public EmailServiceHealthCheck(IEmailService emailService)\n    {\n        _emailService = emailService;\n    }\n\n    public async Task&lt;HealthCheckResult&gt; CheckHealthAsync(\n        HealthCheckContext context,\n        CancellationToken cancellationToken = default)\n    {\n        bool ok = await _emailService.PingAsync(); \/\/ example logic\n\n        if (ok)\n            return HealthCheckResult.Healthy(\"Email service is responding.\");\n        else\n            return HealthCheckResult.Unhealthy(\"Email service failed to respond.\");\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then register it:<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-b8cfe1779551791c09724f00dfe96dec\"><code>builder.Services.AddHealthChecks()\n    .AddCheck&lt;EmailServiceHealthCheck&gt;(\"EmailService\");\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can also pass a <code>failureStatus<\/code> or tags:<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-9fba0aa4f37c24a4c73a0a2ab521e1f8\"><code>.AddCheck&lt;EmailServiceHealthCheck&gt;(\n    \"EmailService\",\n    failureStatus: HealthStatus.Degraded,\n    tags: new&#91;] { \"essential\" });\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tags are handy for grouping and filtering.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Advanced Endpoint Configuration: Readiness, Liveness, Filtering<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In containerized and microservices environments (e.g. Kubernetes), it\u2019s common to separate:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Liveness<\/strong>: Is the application alive (i.e. not crashed)?<\/li>\n\n\n\n<li><strong>Readiness<\/strong>: Are all dependencies healthy so it can accept traffic?<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You can configure multiple endpoints with filtering:<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-f4016846416a40def714f62a8c6a97c4\"><code>app.MapHealthChecks(\"\/health\/live\", new HealthCheckOptions\n{\n    Predicate = _ =&gt; false \/\/ maybe no checks\u2014just liveness\n});\n\napp.MapHealthChecks(\"\/health\/ready\", new HealthCheckOptions\n{\n    Predicate = check =&gt; check.Tags.Contains(\"ready\")\n});\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When registering checks:<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-28acaf8611af42ed24d011f97cccdf36\"><code>builder.Services.AddHealthChecks()\n    .AddSqlServer(connStr, tags: new&#91;] { \"ready\" })\n    .AddRedis(redisConn, tags: new&#91;] { \"ready\" })\n    .AddCheck&lt;EmailServiceHealthCheck&gt;(\"EmailService\", tags: new&#91;] { \"ready\" });\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This way <code>\/health\/live<\/code> might always succeed (if app is running), whereas <code>\/health\/ready<\/code> returns failure if dependencies are failing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can also configure other things in <code>HealthCheckOptions<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Predicate<\/code> to select subset of checks<\/li>\n\n\n\n<li><code>AllowCachingResponses<\/code><\/li>\n\n\n\n<li><code>ResponseWriter<\/code> (to output JSON, detailed info)<\/li>\n\n\n\n<li><code>StatusCodes<\/code> override for mapping <code>Degraded<\/code>\/<code>Unhealthy<\/code> to specific HTTP codes<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You can also short-circuit or branch the pipeline (e.g. <code>ShortCircuit()<\/code>) so health checks don\u2019t run other middleware.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. HealthChecks UI \/ Dashboard<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A core limitation of the default health check endpoint is that it\u2019s raw (text or minimal JSON). To visualize health of multiple services or endpoints, you can use the <strong>HealthChecks UI<\/strong> project (by Xabaril) \u2014 a lightweight dashboard for health checks.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Setup<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Install the following NuGet packages:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>AspNetCore.HealthChecks.UI<\/code> \u2014 the UI frontend &amp; dashboard<\/li>\n\n\n\n<li><code>AspNetCore.HealthChecks.UI.Client<\/code> \u2014 client abstractions <\/li>\n\n\n\n<li>Storage (in-memory or persistent) \u2014 e.g. <code>AddInMemoryStorage()<\/code> <\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Then configure:<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-cc95f3d3409aa6231571d12ca64d8c1a\"><code>\/\/ In ConfigureServices\nbuilder.Services\n    .AddHealthChecks()\n    .AddSqlServer(connStr, tags: new&#91;] { \"ready\" }) \n    \/\/ \u2026 other checks \u2026\n    ;\n\nbuilder.Services.AddHealthChecksUI(options =&gt;\n{\n    options.AddHealthCheckEndpoint(\"My API\", \"\/health\/ready\");\n})\n.AddInMemoryStorage();\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then map the UI middleware:<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-8c5c3e1118028bbc73c650072b1de198\"><code>app.MapHealthChecksUI(ui =&gt;\n{\n    ui.UIPath = \"\/health-ui\";          \/\/ Dashboard path\n    ui.ApiPath = \"\/health-ui-api\";     \/\/ API for internal use\n});\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The UI dashboard will poll the endpoints you configured and show status over time (green, yellow, red). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can host the UI in the same app or in a separate \u201cmonitoring\u201d app (watchdog) that polls multiple services. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Notes &amp; Tips<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The UI internally stores health reports (via a background host) for the frontend to query. <\/li>\n\n\n\n<li>Don\u2019t confuse the UI\u2019s internal API (e.g. <code>\/healthchecks-api<\/code>) with your health endpoints. <\/li>\n\n\n\n<li>For each health endpoint that you want to visualize, you should configure a <code>ResponseWriter<\/code> using <code>UIResponseWriter.WriteHealthCheckUIResponse(...)<\/code> so the UI can parse details.<\/li>\n\n\n\n<li>You can configure webhooks or alerts from UI when a service becomes unhealthy.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Sample Project (Program.cs)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s a consolidated sample <code>Program.cs<\/code> that demonstrates many of the above features:<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-31b51bea78a59ebb76ef0bf8735bfb28\"><code>using HealthChecks.UI.Client;\nusing Microsoft.AspNetCore.Diagnostics.HealthChecks;\n\nvar builder = WebApplication.CreateBuilder(args);\n\n\/\/ Register health checks\nbuilder.Services.AddHealthChecks()\n    .AddSqlServer(builder.Configuration.GetConnectionString(\"Default\"), tags: new&#91;] { \"ready\" })\n    .AddRedis(builder.Configuration&#91;\"Redis:Conn\"], tags: new&#91;] { \"ready\" })\n    .AddCheck&lt;EmailServiceHealthCheck&gt;(\"EmailService\", tags: new&#91;] { \"ready\" });\n\n\/\/ Add HealthChecks UI\nbuilder.Services.AddHealthChecksUI(config =&gt;\n{\n    config.AddHealthCheckEndpoint(\"Main API\", \"\/health\/ready\");\n})\n.AddInMemoryStorage();\n\nvar app = builder.Build();\n\n\/\/ Liveness endpoint \u2014 checks nothing, just app is alive\napp.MapHealthChecks(\"\/health\/live\", new HealthCheckOptions\n{\n    Predicate = _ =&gt; false\n});\n\n\/\/ Readiness endpoint \u2014 checks tagged \u201cready\u201d checks\napp.MapHealthChecks(\"\/health\/ready\", new HealthCheckOptions\n{\n    Predicate = check =&gt; check.Tags.Contains(\"ready\"),\n    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse\n});\n\n\/\/ Health UI dashboard\napp.MapHealthChecksUI(ui =&gt;\n{\n    ui.UIPath = \"\/health-ui\";\n    ui.ApiPath = \"\/health-ui-api\";\n});\n\napp.MapControllers();  \napp.Run();\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You\u2019ll need to write your <code>EmailServiceHealthCheck<\/code> as shown previously, and have connection strings configured in <code>appsettings.json<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Best Practices &amp; Tips<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Use tags consistently<\/strong>: Tag checks (e.g. <code>\"ready\"<\/code>, <code>\"critical\"<\/code>) so you can filter for readiness or partial checks.<\/li>\n\n\n\n<li><strong>Use the UI only for internal or protected endpoints<\/strong> \u2014 don\u2019t expose it publicly unless secured.<\/li>\n\n\n\n<li><strong>Use <code>UIResponseWriter<\/code><\/strong> for endpoints you intend to show on the dashboard, so the UI can parse details.<\/li>\n\n\n\n<li><strong>Customize status codes<\/strong> if you want <code>Degraded<\/code> to return 200 or 429, etc.<\/li>\n\n\n\n<li><strong>Separate liveness vs readiness<\/strong> in container\/orchestrator environments.<\/li>\n\n\n\n<li><strong>Short-circuit health middleware<\/strong> if you want health endpoints to skip expensive middleware (logging, auth, etc.).<\/li>\n\n\n\n<li><strong>Consider a dedicated watchdog service<\/strong> with HealthChecks UI that monitors multiple microservices.<\/li>\n\n\n\n<li><strong>Secure the health endpoints<\/strong> using authentication\/authorization or network rules (firewalls, internal subnets).<\/li>\n\n\n\n<li><strong>Monitor over time<\/strong>: use the UI\u2019s stored results or integrate with metrics systems like Prometheus or Azure Monitor.<\/li>\n\n\n\n<li><strong>Be cautious with expensive checks<\/strong> (like full DB queries) \u2014 health checks should be lightweight and fast.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Health checks in ASP.NET Core are a powerful yet lightweight way to make your application self-aware.<br>With a bit of setup, you can:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Expose liveness \/ readiness endpoints<\/li>\n\n\n\n<li>Monitor dependencies (SQL, Redis, external APIs)<\/li>\n\n\n\n<li>Provide custom logic via <code>IHealthCheck<\/code><\/li>\n\n\n\n<li>Filter and configure endpoints<\/li>\n\n\n\n<li>Visualize health status via dashboards using HealthChecks UI<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">All of this is backed by the Microsoft health check infrastructure <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/host-and-deploy\/health-checks?view=aspnetcore-9.0&amp;utm_source=chatgpt.com\" target=\"_blank\" rel=\"noreferrer noopener\">Microsoft Learn<\/a> and enhanced by community solutions like <strong>AspNetCore.Diagnostics.HealthChecks<\/strong> and <strong>HealthChecks.UI<\/strong> <a href=\"https:\/\/github.com\/Xabaril\/AspNetCore.Diagnostics.HealthChecks?utm_source=chatgpt.com\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub | Microsoft Learn <\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Based on the official Microsoft documentation on health checks in ASP.NET Core Microsoft LearnPlus extensions like HealthChecks.UI from the open-source community GitHub Introduction In modern web APIs, it&#8217;s essential to have self-monitoring baked in. Health checks let your application report its own status, so: This blog covers: 1. Basic Health Probe (Liveness) By default, ASP.NET [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[24,18],"tags":[37,30,39,19],"class_list":["post-217","post","type-post","status-publish","format-standard","hentry","category-business-2","category-software-development","tag-net","tag-c","tag-healthchecks","tag-software"],"_links":{"self":[{"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/posts\/217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/comments?post=217"}],"version-history":[{"count":4,"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/posts\/217\/revisions"}],"predecessor-version":[{"id":224,"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/posts\/217\/revisions\/224"}],"wp:attachment":[{"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/media?parent=217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/categories?post=217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.insync.co.za\/blog\/wp-json\/wp\/v2\/tags?post=217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}