How do I add keyframes to a newly created action with no associated objects?
The key concepts are as follows


animations are composed of fcurves
each fcurve has a data_path and maybe an index
each fcurve has multiple keyframe_points
each keyframe_point has a .co (coordinate), a .handle_left, a .handle_right, and an .interpolation.


You can see an example of an animation built using core python APIs at http://web.purplefrog.com/~thoth/blender/python-cookbook/animate-random-spin.html

I include an excerpt of the most relevant code:

def rig_quaternion_channel(action, channel, period, a, b):
    """
    This is heavy-duty voodoo to figure out what keyframes to use with sinusoidal easing
    to reconstruct a curve of the form
     a*cos(theta) + b*sin(theta)
     by converting it to the form
     c*sin(theta+phi)
    """
    c = sqrt(a * a + b * b)
    phi = -atan2(a, b)
    fc = action.fcurves.new(data_path="rotation_quaternion", index=channel)
    fc.keyframe_points.add(5)
    vals = [0, 1, 0, -1, 0]
    for j in range(5):
        kp = fc.keyframe_points[j]
        frame = 1 + ( phi / (2 * pi) + j / 4.0) * 2 * period
        kp.co = ( frame, c * vals[j])
        kp.interpolation = 'SINE'
        if 0 == j % 2:
            kp.easing = 'EASE_OUT'
        else:
            kp.easing = 'EASE_IN'
    fc.modifiers.new('CYCLES')


Mostly you care about stuff like action.fcurves.new , fc.keyframe_points.add, and kp.co= (frame,value)