diff --git a/LLama/Native/LLamaGrammarElement.cs b/LLama/Native/LLamaGrammarElement.cs
new file mode 100644
index 00000000..6764b285
--- /dev/null
+++ b/LLama/Native/LLamaGrammarElement.cs
@@ -0,0 +1,64 @@
+using System.Runtime.InteropServices;
+
+namespace LLama.Native
+{
+ ///
+ /// grammar element type
+ ///
+ public enum LLamaGrammarElementType
+ {
+ ///
+ /// end of rule definition
+ ///
+ END = 0,
+
+ ///
+ /// start of alternate definition for rule
+ ///
+ ALT = 1,
+
+ ///
+ /// non-terminal element: reference to rule
+ ///
+ RULE_REF = 2,
+
+ ///
+ /// terminal element: character (code point)
+ ///
+ CHAR = 3,
+
+ ///
+ /// inverse char(s) ([^a], [^a-b] [^abc])
+ ///
+ CHAR_NOT = 4,
+
+ ///
+ /// modifies a preceding LLAMA_GRETYPE_CHAR or LLAMA_GRETYPE_CHAR_ALT to
+ /// be an inclusive range ([a-z])
+ ///
+ CHAR_RNG_UPPER = 5,
+
+ ///
+ /// modifies a preceding LLAMA_GRETYPE_CHAR or
+ /// LLAMA_GRETYPE_CHAR_RNG_UPPER to add an alternate char to match ([ab], [a-zA])
+ ///
+ CHAR_ALT = 6,
+ };
+
+ ///
+ /// An element of a grammar
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct LLamaGrammarElement
+ {
+ ///
+ /// The type of this element
+ ///
+ public LLamaGrammarElementType Type;
+
+ ///
+ /// Unicode code point or rule ID
+ ///
+ public uint Value;
+ }
+}
diff --git a/LLama/Native/NativeApi.Grammar.cs b/LLama/Native/NativeApi.Grammar.cs
new file mode 100644
index 00000000..ef36756e
--- /dev/null
+++ b/LLama/Native/NativeApi.Grammar.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace LLama.Native
+{
+ using llama_token = Int32;
+
+ public unsafe partial class NativeApi
+ {
+ //todo: LLAMA_API struct llama_grammar * llama_grammar_init(const llama_grammar_element** rules, size_t n_rules,size_t start_rule_index);
+
+ ///
+ /// Free all memory from the given SafeLLamaGrammarHandle
+ ///
+ ///
+ [DllImport(libraryName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void llama_grammar_free(IntPtr grammar);
+
+ ///
+ /// Apply constraints from grammar
+ ///
+ ///
+ ///
+ ///
+ [DllImport(libraryName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void llama_sample_grammar(SafeLLamaContextHandle ctx, ref LLamaTokenDataArrayNative candidates, SafeLLamaGrammarHandle grammar);
+
+ ///
+ /// Accepts the sampled token into the grammar
+ ///
+ ///
+ ///
+ ///
+ [DllImport(libraryName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern void llama_grammar_accept_token(SafeLLamaContextHandle ctx, SafeLLamaGrammarHandle grammar, llama_token token);
+ }
+}
diff --git a/LLama/Native/SafeLLamaGrammarHandle.cs b/LLama/Native/SafeLLamaGrammarHandle.cs
new file mode 100644
index 00000000..ca814c36
--- /dev/null
+++ b/LLama/Native/SafeLLamaGrammarHandle.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace LLama.Native
+{
+ ///
+ /// A safe reference to a `llama_grammar`
+ ///
+ public class SafeLLamaGrammarHandle
+ : SafeLLamaHandleBase
+ {
+ internal SafeLLamaGrammarHandle(IntPtr handle)
+ : base(handle)
+ {
+ }
+
+ ///
+ protected override bool ReleaseHandle()
+ {
+ NativeApi.llama_grammar_free(handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}