End processing HTTP request after 827.397ms - 400 [verify-otp] Error: {"status_code":400,"request_id":"request-id-live-845d9fbe-6f8d-4a14-965e-0e9af20f5ebd","error_type":"invalid_argument","error_message":"unknown field: \"code\" at line 1:37","error_url

I am trying to use the test api to verify the OTP using code 123456 for the phone number:-+10000000000 but I am getting the issue as {
“status_code”: 400,
“request_id”: “request-id-test-b339fdae-4f56-4fed-b59a-59bcae2c02a6”,
“error_type”: “invalid_argument”,
“error_message”: “unknown field: "code" at line 3:1”,
“error_url”: “Errors - Stytch API
}
I tried each and every best way to resolve it but it is not working

Hey Niki – thanks for posting!

Would you mind sharing the full request that you’re making? I’d be happy to see if I can spot the issue.

Okay I am sharing my verify otp api

Please refer the document attached to this email.

(Attachment Stytch_Send&Verify_Api.txt is missing)

using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

var builder = WebApplication.CreateBuilder(args);

// Razor Pages and Swagger
builder.Services.AddRazorPages();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Load Stytch credentials from environment variables
var stytchProjectId = Environment.GetEnvironmentVariable(“STYTCH_PROJECT_ID”);
var stytchSecret = Environment.GetEnvironmentVariable(“STYTCH_SECRET”);

if (string.IsNullOrWhiteSpace(stytchProjectId) || string.IsNullOrWhiteSpace(stytchSecret))
{
Console.WriteLine(“ERROR: STYTCH_PROJECT_ID and STYTCH_SECRET must be set as environment variables.”);
return;
}

// Register typed HttpClient with Basic Auth
builder.Services.AddHttpClient(“Stytch”, client =>
{
var authHeader = Convert.ToBase64String(Encoding.ASCII.GetBytes($“{stytchProjectId}:{stytchSecret}”));
client.BaseAddress = new Uri(“https://test.stytch.com/v1/”);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Basic”, authHeader);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(“application/json”));
});

var app = builder.Build();
//app.UseStaticFiles();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();

// Send OTP - using login_or_create to trigger OTP
app.MapPost(“/send-otp”, async (HttpRequest request, IHttpClientFactory clientFactory) =>
{
try
{
var data = await JsonSerializer.DeserializeAsync<Dictionary<string, string>>(request.Body);
if (data == null || !data.TryGetValue(“phone_number”, out var phoneNumber))
{
return Results.BadRequest(new { error = “phone_number is required” });
}

var payload = new { phone_number = phoneNumber };
var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, “application/json”);

var client = clientFactory.CreateClient(“Stytch”);
var response = await client.PostAsync(“otps/sms/login_or_create”, content);
var responseContent = await response.Content.ReadAsStringAsync();

if (!response.IsSuccessStatusCode)
{
Console.WriteLine($“[send-otp] Error: {responseContent}”);
return Results.BadRequest(new { error = “Failed to send OTP”, details = responseContent });
}

return Results.Ok(new { message = “OTP sent successfully” });
}
catch (Exception ex)
{
Console.WriteLine($“[send-otp] Exception: {ex.Message}”);
return Results.StatusCode(500);
}
});

// Verify OTP
app.MapPost(“/verify-otp”, async (HttpRequest request, IHttpClientFactory clientFactory) =>
{
try
{
using var reader = new StreamReader(request.Body);
var body = await reader.ReadToEndAsync();
var otpRequest = JsonSerializer.Deserialize(body);

if (otpRequest == null || string.IsNullOrWhiteSpace(otpRequest.PhoneNumber) || string.IsNullOrWhiteSpace(otpRequest.OtpCode))
{
return Results.BadRequest(new { error = “phone_number and otp_code are required” });
}

var payload = new
{
phone_number = otpRequest.PhoneNumber,
code = otpRequest.OtpCode
};

var jsonPayload = JsonSerializer.Serialize(payload);
Console.WriteLine($“[verify-otp] Sending JSON: {jsonPayload}”);
var content = new StringContent(jsonPayload, Encoding.UTF8, “application/json”);

var client = clientFactory.CreateClient();
client.BaseAddress = new Uri(“https://api.stytch.com/v1/”);
// Set Basic Auth header
var authValue = Convert.ToBase64String(Encoding.ASCII.GetBytes($“{stytchProjectId}:{stytchSecret}”));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Basic”, authValue);

var response = await client.PostAsync(“otps/sms/login_or_create”, content);
var responseContent = await response.Content.ReadAsStringAsync();

if (!response.IsSuccessStatusCode)
{
Console.WriteLine($“[verify-otp] Error: {responseContent}”);
return Results.BadRequest(new { error = “OTP verification failed”, details = responseContent });
}

var resultJson = JsonSerializer.Deserialize(responseContent);
return Results.Ok(new { message = “OTP verified successfully”, data = resultJson });
}
catch (Exception ex)
{
Console.WriteLine($“[verify-otp] Exception: {ex}”);
return Results.StatusCode(500);
}
});
app.Run();

public class OtpRequest
{
[JsonPropertyName(“phone_number”)]
public string PhoneNumber { get; set; }

[JsonPropertyName(“otp_code”)]
public string OtpCode { get; set; }
}

I find it interesting this error is being reported just yesterday as it’s the only reference to “unknown field” I can find on the Stytch forum. I’m just starting out with Stytch and am working with their Management API. I’m using it to pull an exisitng email template, turning around and sending the template right back to the API as a copy or a simple edit where I just add a letter on the Subject and I’m getting the same error for whatever the first field happens to be in the JSON… even though it’s the exact fields, unaltered, that came down from Stytch in the first place. For the email template (usually it’s the template_id) field that comes first and thus that it says is unknown. Makes me wonder if something is going on.

“{"status_code":400,"error_message":"unknown field: \"template_id\" at line 1:2","error_type":"invalid_argument","request_id":"request-id-prod-f2d61920-f63b-4717-8586-d21f4868a679"}”

Hey Niki - thanks for sharing that!

A couple of things here:

  1. It looks like you’re passing the code parameter to our SMS OTP Login or Create endpoint, rather than our OTP Authenticate endpoint. It looks like you may be calling /otps/sms/login_or_create where you should be calling /otps/authenticate - the second call to /login_or_create underneath the // Verify OTP comment.
  2. In the second call (that should be to /authenticate), you’re passing in the phone number rather than the method_id (which is the phone_id value returned in the response to the /login_or_create call).

You can see the required request parameters and response structure of both endpoints here:

We also have a guide to implementing SMS OTP with a backend integration here that I’d definitely recommend checking out!

Essentially, you’ll just need to switch the second /login_or_create call to an /authenticate call and adjust the parameters you’re passing in to the second call!


@Wesley - the “unknown field” error you’re experiencing looks to be a different root cause!

Would you mind either creating a new thread in the Forum (or emailing us at support@stytch.com or posting in our community Slack), sharing the structure of the email_template body parameters that you’re passing in to this call (and how you’re calling the POST endpoint generally)?

Thanks!

I’ve created a Forum post just in case whatever I’m doing wrong can help other people not make the same mistake: https://forum.stytch.com/t/unknown-field-errors-working-with-email-templates-in-management-api/389