diff --git a/include/samtools.h b/include/samtools.h
--- a/include/samtools.h
+++ b/include/samtools.h
@@ -44,4 +44,7 @@
 
 void bam_init_header_hash(bam_header_t *header);
 
+/* Prototype for bam_aux.c function */
+void bam_aux_append(bam1_t *b, const char tag[2], char type, int len, uint8_t *data);
+
 #endif /* _samtools_h */
diff --git a/samtools.cabal b/samtools.cabal
--- a/samtools.cabal
+++ b/samtools.cabal
@@ -1,5 +1,5 @@
 Name:                samtools
-Version:             0.2.3
+Version:             0.2.4
 Synopsis:            Binding to the C samtools library
 Description:         Binding to the C samtools library, which reads and
                      writes SAM format alignments, both binary and tab-
diff --git a/src/Bio/SamTools/Bam.hs b/src/Bio/SamTools/Bam.hs
--- a/src/Bio/SamTools/Bam.hs
+++ b/src/Bio/SamTools/Bam.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}
 
 -- | This module provides a fairly direct representation of the
 -- SAM/BAM alignment format, along with an interface to read and write
@@ -30,6 +30,8 @@
   , mateTargetID, mateTargetName, mateTargetLen, matePosition, insertSize
     
   , nMismatch, nHits, matchDesc, auxGeti, auxGetf, auxGetd, auxGetA, auxGetZ, auxGet
+
+  , addAuxA, addAuxi, addAuxZ
                                                                
   , refSpLoc, refSeqLoc
                       
@@ -292,6 +294,45 @@
 
 instance AuxGet BS.ByteString where
   auxGet b str = auxGetZ b str
+
+addAuxA :: Bam1 -> String -> Char -> IO Bam1
+addAuxA b0 tag ch
+  = alloca $ \(valptr :: (Ptr CChar)) -> do
+      poke valptr (CChar . fromIntegral . fromEnum $ ch)
+      addAux b0 tag typecchar vallen (castPtr valptr)
+  where typecchar = (CChar . fromIntegral . fromEnum $ 'A') 
+        vallen = fromIntegral $ sizeOf (undefined :: CChar)
+
+addAuxi :: Bam1 -> String -> Int -> IO Bam1
+addAuxi b0 tag i
+  = alloca $ \(valptr :: (Ptr CInt)) -> do
+      poke valptr (CInt . fromIntegral $ i)
+      addAux b0 tag typecchar vallen (castPtr valptr)
+  where typecchar = (CChar . fromIntegral . fromEnum $ 'i')
+        vallen = fromIntegral $ sizeOf (undefined :: CInt)
+
+addAuxZ :: Bam1 -> String -> String -> IO Bam1
+addAuxZ b0 tag str
+  = withCAString str $ \cstr -> do
+      strlen <- lengthArray0 (0 :: CChar) cstr
+      addAux b0 tag typecchar (CInt . fromIntegral $ strlen + 1) (castPtr cstr)
+  where typecchar = (CChar . fromIntegral . fromEnum $ 'Z')
+
+addAux :: Bam1 -> String -> CChar -> CInt -> Ptr CUChar -> IO Bam1
+addAux b0 tag typecchar vallen valptr
+  | Prelude.length tag == 2 = withForeignPtr (ptrBam1 b0) $ \pbi0 ->
+    do pb' <- bamDup1 pbi0 >>= newForeignPtr bamDestroy1Ptr
+       withForeignPtr pb' $ \pbi' ->
+         withCAStringLen tag $ \(tagstr, _tagstrlen) ->
+           bamAuxAppend pbi' tagstr typecchar vallen valptr
+       return $ Bam1 { ptrBam1 = pb', header = header b0 } 
+  | otherwise = ioError . userError $ "Bad BAM Aux tag " ++ show tag
+
+-- bamAuxAppend :: Bam1Ptr -> Ptr CChar -> CChar -> CInt -> Ptr CUChar -> IO ()
+
+--    else do bptr <- newForeignPtr bamDestroy1Ptr b
+--            return . Just $ Bam1 { ptrBam1 = bptr, header = inHeader inh }
+
 
 -- | 'Just' the match descriptor alignment field, or 'Nothing' when it
 -- is absent
diff --git a/src/Bio/SamTools/LowLevel.chs b/src/Bio/SamTools/LowLevel.chs
--- a/src/Bio/SamTools/LowLevel.chs
+++ b/src/Bio/SamTools/LowLevel.chs
@@ -29,6 +29,8 @@
                              , bamAuxGet, bamAux2Z, bamAux2i, bamAux2f, bamAux2d, bamAux2A
                                                                                                  
                              , bamInit1, bamDestroy1, bamDestroy1Ptr, bamDup1, bamFormat1
+
+                             , bamAuxAppend
                              
                              , BamIndexInt, BamIndexPtr
                              , bamIndexLoad, bamIndexDestroy
@@ -293,6 +295,14 @@
 
 {#fun unsafe bam_format1 as bamFormat1
  { id `BamHeaderPtr', id `Bam1Ptr' } -> `CString' id#}
+
+{#fun unsafe bam_aux_append as bamAuxAppend
+ { id `Bam1Ptr'
+ , id `Ptr CChar'
+ , id `CChar'
+ , id `CInt'
+ , id `Ptr CUChar' }
+ -> `()'#}
 
 -- BAM indexing
 
diff --git a/test/SamTest.hs b/test/SamTest.hs
--- a/test/SamTest.hs
+++ b/test/SamTest.hs
@@ -5,6 +5,7 @@
 import Control.Exception
 import Control.Monad
 import qualified Data.ByteString.Char8 as BS
+import Data.List
 import Data.Maybe
 import System.Environment
 import System.Exit
@@ -51,6 +52,21 @@
 
                      bracket (Bam.openBamInFile bamin) Bam.closeInHandle $ \hin ->
                        Bam.get1 hin >>= maybe (return ()) (parseBam (Bam.inHeader hin))
+
+                     addAuxFields bamin >>= hPutStrLn stderr
+
+addAuxFields :: FilePath -> IO FilePath
+addAuxFields inname = let outname = dropExtension inname ++ "-auxa.bam"
+                      in bracket (Bam.openBamInFile inname) Bam.closeInHandle $ \hin ->
+                        bracket (Bam.openBamOutFile outname (Bam.inHeader hin)) Bam.closeOutHandle $ \hout -> do
+                          myloop hin hout 0
+                          return outname
+  where myloop hin hout idx = Bam.get1 hin >>= maybe (return ()) (\b -> go b >> myloop hin hout (idx + 1))
+          where go b = Bam.addAuxA b "XX" 'm' >>= (\b' -> Bam.addAuxi b' "YZ" idx) >>= 
+                       (\b'' -> Bam.addAuxZ b'' "aa" (digitName $ idx `mod` 10)) >>=
+                       Bam.put1 hout
+        digitName i | i < 0 || i > 9 = show i
+                    | otherwise = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"] !! i
 
 bamToSam :: FilePath -> IO FilePath
 bamToSam inname = let outname = dropExtension inname ++ "-test.sam"
