I had problems originally using the method you are using to write the contents of the json to the endpoint - using (HttpWebRequest)WebRequest.Create() - this didn’t work for me and I got a very unhelpful not authorized message.
I’m now using a very old version of RestSharp library NuGet Gallery | RestSharp 104.0.0 and note the 104.0.0 version.
The reason is that I got this working originally with the Postman Twitter API v2 (Twitter API v2), and when I put in my keys and did a test POST it worked, and it also allows you to generate C# RestSharp code for the same request, for me it looked like this:
var client = new RestClient("https://api.twitter.com/2/tweets");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", auth);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Cookie", "guest_id=v1%3A164647635225822612");
var body = @"{" + "\n" +
@" ""text"": ""Hello World!""" + "\n" +
@"}";
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
The new version of RestSharp however doesn’t work with this, but that old 104.0.0 version does. When I used this code to make my request with the same auth header it worked!
Maybe worth a shot?
For completeness, the method I used to get the header is from GitHub - rhargreaves/oauth-dotnetcore: An implementation of OAuth 1.0a for .NET Core based on Daniel Crenna’s vaulted OAuth library
OAuthRequest oAclient = OAuthRequest.ForProtectedResource("POST", CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
oAclient.RequestUrl = "https://api.twitter.com/2/tweets";
string auth = oAclient.GetAuthorizationHeader();
Also, for settings in the developer portal, I assume you enabled the correct version of oAuth, and that you have oauth 1.0a settings / Read and write Read and Post Tweets and profile information selected, and that you have URLs in the Callback URI / Redirect URL, and the Website URL (even if they are blank webpages I think you may still need to have them entered and valid?).
I recommend the Postman API addon first to confirm your keys are all good - you might need to clone it to enter your keys to get it working - if that POSTs with your keys then you know it’s your code and not your keys! Note that I couldn’t get Postman working with the same keys without the add-on v2 API workspace!