Optimizely Forms built-in webhook: how to add a dynamic JWT header per submission?

Vote:
 

Hi,

I’m using Optimizely/Episerver Forms (Forms Core 5.10.x) in an ASP.NET Core site (.NET 8). I have a custom PostSubmissionActor where I can obtain a JWT (Okta client_credentials) at submit time.

I want to keep using the built-in Forms webhook/external system (configured in the Form UI), but include a JWT in an HTTP header (e.g. Authorization: Bearer <jwt> or X-My-Jwt: <jwt>) on the outgoing webhook request.

From what I can tell: A PostSubmissionActor can mutate SubmissionData.Data (the body) but I can’t find a supported extension point to inject/override headers for the built-in webhook HTTP request.

Questions

  1.  Is there a supported way in Optimizely Forms to add dynamic per-submission HTTP headers to the built-in webhook request?
  2.  If not, what is the recommended pattern?
    •    Implement the HTTP POST inside a custom PostSubmissionActor (and disable/remove the built-in webhook on that form to avoid double-calls)?
    •    Use a relay/proxy endpoint where Forms posts normally, and the relay adds the JWT header when forwarding?

Current actor approach (can only add JWT to body):

public class EpihooksFormsSubmissionActor : PostSubmissionActorBase, ISyncOrderedSubmissionActor
{
    public override object Run(object input)
        => Task.Run(AddJwtToSubmissionBody).GetAwaiter().GetResult();

    private async Task<object> AddJwtToSubmissionBody()
    {
        var jwt = await JwtUtility.GetJwtToken(authorityUrl, scope, clientId, clientSecret);
        SubmissionData?.Data?.Remove("jwt");
        SubmissionData?.Data?.Add("jwt", jwt);
        return string.Empty;
    }
}

If it matters: I only need this behavior for specific forms (not all forms), and I want to avoid double-posting.
Any official references or suggested approaches would help.

 

Regards.

#341783
Feb 24, 2026 20:06
Vote:
 

Basically, I did it this way:

  1. Create class CustomActorConfigModel : IPostSubmissionActorModel, ICloneable containing virtual string? ConfigKey and virtual string? ConfigValue. These would be available on all forms and is used for settings; like "IntegrateWithBusinessSystem": "true"
  2. Create custom Actor; in your Run method invoke var configs = Model as IEnumerable<CustomActorConfigModel>;  If its null or has no rows, consider as normal form and just return empty string. In other case continue and check the configs object for matching value(s) to validate that you should carry on with your custom JWT implementation.
  3. If all successful return SuccessfulSubmissionResult(), else a SubmissionErrorResult with the error message.

 

 

 

 

[Serializable]
public class CustomActorConfigModel : IPostSubmissionActorModel, ICloneable
{
    [Display(
      Name = "Config Key",
      Order = 1000)]
    public virtual string? ConfigKey { get; set; }

    [Display(
      Name = "Config Value",
      Order = 1100)]
    public virtual string? ConfigValue { get; set; }

    #region ICloneable Members

    public object Clone()
    {
      return new CustomActorConfigModel
      {
        ConfigKey = this.ConfigKey,
        ConfigValue = this.ConfigValue,
      };
    }

    #endregion
}
#341785
Feb 25, 2026 12:55
Farhin - Feb 26, 2026 18:38
Thanks, Jonas, for responding. This is exactly what I was looking for—I couldn’t find a clear reference point for implementing this, especially the part about adding a custom property to the Form Container. Your approach works great.
I do have one minor question: with this new custom property in place—just to confirm my understanding—I no longer need to specify the API endpoint in the default “Trigger webhook after form submission” Webhook URL field, correct?
Jonas Boman - Feb 27, 2026 8:01
I am glad I could help. No, the approach above would make the webhook not neccesary since you are doing it all in your custom actor.
Vote:
 

I think using relay/proxy endpoint is the simplest approach here, instead of modifying the built-in Forms webhook request, let Forms post normally to your own endpoint, and let that endpoint get the form submission, obtain the JWT, forward the request to its destination external system adding the Authorization header with the token you recieved in your relay endpoint.

#341797
Feb 25, 2026 17:25
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.